Version 21 of Variable Substitution

Updated 2014-06-23 05:40:56 by pooryorick

Variable substitution, one of the substitutions defined in the dodekalogue, is one of the mechanisms for retrieving the value of variables in Tcl.

set v aValue
puts $v

The $v notation tells Tcl to retrieve the value of the variable v, whose value is

aValue

The $ notation was added to Tcl for coding convenience and is short for

set v

The following lines are equivalent:

puts $v
puts [set v]

When dynamically composing 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, but 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}

Using set in place of the $ variable can help to illuminate the behaviour of Tcl:

Replacing the $ notation by a $ call, the following line pairs are equivalent:

foreach i {1 2 3} {puts $var$i} ;# this fails because $var is undefined
foreach i {1 2 3} {puts [set var][set i]} ;# this fails because $var is undefined

foreach i {1 2 3} {puts [set var$i]}
foreach i {1 2 3} {puts [set var[set i]]}

When accessing an array variable, the member name is computed and then looked up in the array, so arrays are a good fit when programming in a style that leads to composition of variable names:

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 [set var([set i])]}

Although there are often better alternatives to variable indirection, it can be implemented in the following ways:

set a something
set pointer a
puts [set $pointer] ;#good style
puts [set [set pointer]] ;#more verbose style
eval puts \$$pointer ;#oh blimey, it's "eval"!  Run away!

See also

set
variable
double substitution and Dereferencing
how do i do $$var - double dereferencing a variable
Variable substitution in -command scripts
Quoting Hell