http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/set.htm set - Read and write variables set varName ?value? Returns the value of variable varName. If value is specified, then set the value of varName to value, creating a new variable if one doesn't already exist, and return its value. If varName contains an open parenthesis and ends with a close parenthesis, then it refers to an array element: the characters before the first open parenthesis are the name of the array, and the characters between the parentheses are the index within the array. Otherwise varName refers to a scalar variable. Normally, varName is unqualified (does not include the names of any containing namespaces), and the variable of that name in the current namespace is read or written. If varName includes namespace qualifiers (in the array name if it refers to an array element), the variable in the specified namespace is read or written. If no procedure is active, then varName refers to a namespace variable (global variable if the current namespace is the global namespace). If a procedure is active, then varName refers to a parameter or local variable of the procedure unless the global command was invoked to declare varName to be global, or unless a variable command was invoked to declare varName to be a namespace variable. (From: Tcl Help) ---- The reading form ''set x'' (without value) works the same as ''$x'', so you could write Tcl scripts without a single dollar sign. It's advantage is that it can be nested, so multiple dereferencing is possible: set foo 1 set bar foo puts [set $bar] ;# retrieves indirectly the value of foo puts [set [set bar]] ;# equivalent, but less readable See also "An essay on Tcl dereferencing" [http://starbase.neosoft.com/~claird/comp.lang.tcl/tcl_deref.html] ---- When a proc is left without a ''[return]'', it returns the last evaluated result. It is therefore an idiom (and it used to be even faster, before ''[return]'' was byte-compiled) to write set res as last command in a proc instead of return $res The danger is that someone might add code after the set statement, so the expected result would be lost... ---- As Tcl has no reserved words, you can even write your own set command (make sure its effects are like the original, otherwise most Tcl code might break). For instance, this version says what it does, on stdout: rename set _set proc set {var args} { puts [list set $var $args] uplevel 1 _set $var $args } ;#RS Might help in finding what was going on before a crash. When sourced in a wish app, shows what's up on the Tcl side of Tk. Pretty educative! ---- How can I do a double indirect? - Why doesn't $$var work? There is one and only one level of substitution possible with every pass through the interpreter. Also, when doing variable substitution, the interpreter finds the dollar sign and then takes everything following it up until the next invalid character (where invalid is defined as anything other than a letter, digit, or underscore) as the name of the variable - well, that is, unless it finds array notation or the ${varname} form. In the case of $$var, the character after the first dollar sign is an invalid character (another dollar sign), so there is no variable name and variable substitution is not performed (the dollar sign is left as is) and scanning starts again for any dollar signs and a following variable name. It is immediately found at that second dollar sign, the substitution is performed, and scanning for dollar signs resumes with whatever was after the variable name. Since there isn't anything else, substition is done for this pass through the interpreter (remember it's only done once). The eval command runs its arguments through the interpreter, so you could use eval to cause a second pass through the interpreter, and thus, have $$var work: % set a 5 5 % set var a a % puts $$var ;# This doesn't work $a % eval puts $$var ;# This does - but it's dangerous 5 However, if the contents of var contain any special characters (e.g. whitespace, semicolon) you'll run into problems. A better method is to take advantage of the behaviour of the set command when given only one argument, and combine command substitution with variable substitution: % puts [set $var] ;# This works safely 5 or, in fact, you could use just command substitution (which is performed once for each [[ ] pair): % puts [set [set var]] ;# as does this 5 Similarly, to print the values of var1, var2, and var3: set var1 3.14159 set var2 hello set var3 13 foreach num {1 2 3} { puts "var$num = [set var$num]" } will output: var1 = 3.14159 var2 = hello var3 = 13 The upvar command can also be used to derefence variables. In addition, the interpreter includes the command subst which can be used to perform substitutions. Note that all of the above applies to array variables also. ---- [Tcl syntax help] - [Arts and crafts of Tcl-Tk programming] - [Category Command]