Tcl Part I · Module 3 · Values, Variables, and Expressions
set and $var: Creating and Reading a Variable
You have been using set since the first module, so most of this chapter confirms what you already do. Three things are worth slowing down for, because none of them is obvious and all three come up constantly. set hands back the value it stored, which explains why the interactive prompt echoes. set with a single argument reads instead of writing. And because that reading form takes the name as an ordinary value, it is how you reach a variable whose name was not known when you wrote the line.
Foundation12 min readTclPart IValuesVariablesset
Part I · Module 3 · Chapter 3.2 · set and $var: Creating and Reading a Variable
1. The Basic Shape
set takes a name and a value:
set stage parse
set count 0
set message "ready to run"
puts $stage
puts $count
puts $messageparse
0
ready to runTwo words after the command: the name, then the value. No declaration, no type, and nothing to do first — set creates the variable if it does not exist and overwrites it if it does.
set stage parse
puts $stage
set stage compile
puts $stageparse
compile2. Reading With $
$name substitutes the value, which is Chapter 2.4:
set unit cm
puts "measured in $unit"
puts "doubled label: ${unit}${unit}"measured in cm
doubled label: cmcmNothing new here. It is listed so the two halves sit together: set writes, $ reads.
3. set Returns the Value It Stored
This is the first thing worth knowing that is not obvious:
puts "set returns: [set stage parse]"
set a [set b 5]
puts "a = $a, b = $b"set returns: parse
a = 5, b = 5set is a command like any other, and like most commands it returns something. It returns the value it just stored.
That explains something from Chapter 1.5: at the interactive prompt, set greeting "good morning" echoed good morning. The prompt was displaying set's return value, not announcing what it had done.
It also means you can store and use in one step, as the set a [set b 5] line does. That is occasionally handy and easy to overuse — two plain lines are usually clearer.
4. set With One Argument Reads
Give set only a name and it reads instead of writing:
set stage parse
puts $stage
puts [set stage]parse
parseBoth lines do the same thing. $stage and [set stage] are the same operation written two ways.
$stage is shorter and is what you should write almost always. So why does the other form exist?
5. Because the Name Can Be Computed
Here is the payoff. set takes the name as an ordinary word — which means the name can come from a variable:
set stage parse
set which stage
puts "which holds: $which"
puts "indirect read: [set $which]"which holds: stage
indirect read: parseRead the last line carefully. $which substituted to stage, so the command became set stage, which read the variable called stage and returned parse.
You cannot write that with $ alone. $$which does not mean "the variable named by which" — Chapter 2.2 explains why: substitution happens once, so the result of $which is not substituted again.
Writing to a computed name works the same way:
set target counter
set $target 10
puts "counter is now $counter"counter is now 106. Values Are Copied, Not Shared
A small but important behaviour:
set original "first"
set copy $original
set original "changed"
puts "original: $original"
puts "copy: $copy"original: changed
copy: firstset copy $original stored the value that $original had at that moment. Changing original afterwards did not reach copy.
This is worth stating because engineers arriving from hardware description languages sometimes expect an assignment to describe an ongoing relationship. It does not. It happens once, when the line runs.
7. A Variable Holds One Value
There is no "multiple assignment" in the Python sense:
set a 1
set b 2
puts "$a $b"Each set does one variable. If you want several related values in one place, that is what lists and dictionaries are for — Modules 6 and 7.
8. Reading a Variable That Does Not Exist
puts $notherecan't read "nothere": no such variableAn error, not an empty string. That is deliberate and it is a good thing — a typo in a variable name stops the script instead of quietly producing blank output.
How to check first, and how to supply a default, is Chapter 3.4.
9. Common Mistakes
Putting $ on the name when writing. set $stage parse sets the variable named by the value of stage. §5.
Expecting a declaration. There is none. set creates on first use.
Expecting assignment to link two variables. §6. It copies the value once.
Using [set x] where $x would do. Correct but unidiomatic. Reserve it for computed names.
Assuming an unset variable reads as empty. It raises an error. §8.
10. Exercises
Exercise 1 — write, read, overwrite. Create a variable, print it, overwrite it, print it again. Then print the return value of the overwriting set on the same line, using puts "[set ...]".
Exercise 2 — the two reading forms. Show that $name and [set name] give the same answer for the same variable. Then say in one sentence when you would choose the longer form.
Exercise 3 — indirect read. Create a variable colour holding blue, and a variable pick holding colour. Print blue using only pick — you may not write $colour anywhere.
Exercise 4 — predict the copy. Before running:
set x 10
set y $x
set x 99
puts "$x $y"Exercise 5 — the chained set. Predict and then check:
set p [set q [set r 3]]
puts "$p $q $r"Explain the result using §3.
Exercise 6 — deliberate failure. Read a variable you never set, and read the error. Then set it and confirm the error goes away. Why is an error better than an empty value here?
11. Remember
set name valuewrites. It creates the variable if needed and overwrites it if it exists.- The name is a plain word — no
$on the left for a normal assignment. setreturns the value it stored, which is why the interactive prompt echoes it.set namewith one argument reads, and$nameis the same operation written shorter.- The one-argument form takes the name as a value, so it can read a variable whose name was computed. Use it sparingly.
- Assignment copies the value once. It does not link two variables.
- Reading a variable that does not exist is an error, not an empty string.
Next: what Tcl actually allows in a variable name, which is far more than you would guess.
Where this fits
Part of the Tcl curriculum.
