[ulis], 2003-08-31 ** See also ** * [set] * [variable] * [double substitution] and [Dereferencing] * [how do i do $$var - double dereferencing a variable] * [Variable substitution in -command scripts] * [Quoting Hell] Variable substitution is the way Tcl gets a value from a name: ====== set v aValue puts $v ====== The $v notation tells Tcl to get the value of the variable v, whose value is ======none aValue ====== The $ notation was added to Tcl for coding convenience as a shorter way to express ====== set v ====== The following lines are equivalent: ====== puts $v puts [set v] ====== When dynamically compoing a variable name, set can be used where `$` can't. In the following example, Tcl substitutes the value of i and then set returns the value of var1, var2, var3. ====== foreach i {1 2 3} { puts [set var$i] } ====== The following code fails because Tcl tries to substitute $var and then $i, and finds that var is not defined. ====== #warning: example of bad code foreach i {1 2 3} { puts $var$i } ;# this fails because $var is undefined ====== Another approach that is not recommended: ====== foreach i {1 2 3} {eval puts \$var$i} ====== though possibly prone to syntactical issues (like special characters), you could rightfully and reasonable write: without the extra 'eval', which evaluates its argument list once, you'd get the logical and desirable intermedeate result: ====== % foreach i {1 2 3} { puts "\$var$i" } $var1 $var2 $var3 ====== ====== foreach i {1 2 3} { set var$i value$i } foreach i {1 2 3} { puts $var$i } ;# this fails because $var is undefined(var is undefined) ====== To best understand what happens when Tcl is substituting variables let's define a $ alias that does the $ substitution: ====== interp alias {} $ {} set ====== Replacing the $ notation by a $ call, the following lines are equivalent two by two: ====== foreach i {1 2 3} {puts $var$i} ;# this fails because $var is undefined foreach i {1 2 3} {puts [$ var][$ i]} ;# this fails because $var is undefined foreach i {1 2 3} {puts [set var$i]} foreach i {1 2 3} {puts [$ var[$ i]]} ====== Composing the name of a variable is a clear signal that an array could be used: ====== foreach i {1 2 3} {set var($i) value$i} foreach i {1 2 3} {puts $var($i)} ====== The last line is equivalent to: ====== foreach i {1 2 3} {puts [$ var([$ i])]} ====== ---- [TV] It could also indicate an indirection, an important programming concept, and in some form a major language discussion issue in the history of tcl/tk: ====== set a something set pointer a eval puts "\$$pointer" ====== [ulis] The last line is equivalent to: ====== puts [set [set pointer]] ====== ''^-amended slightly by [FW]'' And can be rewritten, avoiding eval: ====== puts [set $pointer] ====== <> Tutorial