2
set lambda 1

set lambdaR [open LamdaValue.tr r]
  set Reader [read $lambdaR]
  close $lambdaR

foreach {x} $Reader {
   set lambda $x
  }
set $lambda [expr {$lambda + 1.0}]
set LambdaW [open LamdaValue.tr w]
puts $LambdaW "$lambda"

I'm trying to use this snippet of code to read the value of lambda from a file, modify it, and then write it to the file again. I'm using ns-2 which deals with tcl execution files. But the value of lambda doesn't change... Can you spot where's the error?

Shaikha TheGreen
  • 115
  • 2
  • 12

1 Answers1

3

It's best to write a small procedure to read the file and return its contents, and another to write the value back out.

proc readfile {filename} {
    set f [open $filename]
    set data [read $f]
    close $f
    return $data
}
proc writefile {filename data} {
    set f [open $filename w]
    puts -nonewline $f $data
    close $f
}

Then you can simplify the rest of your code a lot:

set lambda 1
# The catch means we use the fallback if the file doesn't exist
catch {set lambda [readfile LamdaValue.tr]}

set lambda [expr {$lambda + 1.0}]

writefile LamdaValue.tr $lambda

The other problem you were having was that you were doing set $lambda. This creates a variable with a strange name. In Tcl, you need to distinguish between reading the variable, when you use $, and naming variable (so a command can update it), when you don't use $. Unless you're wanting to keep the name of one variable in another variable, but it's best to only use that with upvar really to reduce confusion, or to switch to using array elements.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • You are right it worked. Thanks. But I want to ask does that have to do with closing the file after each write and read? – Shaikha TheGreen Mar 21 '15 at 18:44
  • Would you want `read -nonewline $f` or `read $f [file size $filename]` ? – glenn jackman Mar 21 '15 at 20:18
  • @ShaikhaTheGreen It reads the whole file in and writes it out in one go too. It's the simplest thing that might work. You can do other approaches too; this is an area where there a _lot_ of options. – Donal Fellows Mar 22 '15 at 17:33
  • @glennjackman I don't know whether `read -nonewline` is suitable, but using `read` with a length is not really necessary now; the buffer management is now efficient enough that it is no big deal to just the single-argument form. – Donal Fellows Mar 22 '15 at 17:35