'''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 ======none 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]: <> Tutorial