Skip to content
VLSI Mentor

Tcl Part I · Module 2 · The Tcl Execution Model

Variable Substitution: $name

You have been writing $name since Module 1 without being told the rule behind it. The rule is small: Tcl reads the name as letters, digits and underscores, and stops at the first character that is not one of those. Nearly everything practical about variable substitution follows from that one sentence, including why ${name} exists, why a trailing letter can silently break a line, and why a dollar sign in ordinary text sometimes causes an error you did not expect.

Foundation12 min readTclPart IExecution ModelSubstitutionVariables

Part I · Module 2 · Chapter 2.4 · Variable Substitution: $name

1. What It Does

$name tells Tcl: replace this with the value stored under that name.

Azvya Education Pvt. Ltd.VLSI Mentor
basic.tcl
set language Tcl
puts $language
puts "Language: $language"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
Tcl
Language: Tcl

Both lines substituted. The second shows that substitution happens inside double quotes too — Chapter 2.7 explains why.

2. The Rule

Here is the whole thing:

After $, Tcl reads letters, digits and underscores. It stops at the first character that is not one of those.

Nothing else to memorise. The rest of this chapter is that rule applied.

3. Watching the Name End

Each of these ends the name at a different character:

Azvya Education Pvt. Ltd.VLSI Mentor
boundaries.tcl
set unit cm

puts "plain:      $unit"
puts "with dash:  $unit-s"
puts "with dot:   $unit."
puts "with slash: $unit/min"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
plain:      cm
with dash:  cm-s
with dot:   cm.
with slash: cm/min

In every case Tcl read unit, stopped at the next character, and left that character alone. The dash, the dot and the slash are not part of the name, so they are ordinary text.

4. When the Rule Works Against You

Now a case where the rule does something you did not want:

Azvya Education Pvt. Ltd.VLSI Mentor
runon.tcl
set unit cm
puts "$units"

Predict the output before reading on. Many people expect cms.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
can't read "units": no such variable
    while executing
"puts "$units""
    (file "runon.tcl" line 2)

Tcl did not read unit and then an s. s is a letter, so it is part of the name. Tcl looked for a variable called units, and there is not one.

Nothing is wrong with the rule. The rule is doing exactly what §2 says. The problem is that you wanted the name to end before the s, and nothing in the text said so.

${name} is how you say so:

Azvya Education Pvt. Ltd.VLSI Mentor
braced-name.tcl
set unit cm
puts "${unit}s"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
cms

The braces mark where the name ends. Tcl reads unit, sees the closing brace, and the s after it is ordinary text.

5. A Second Case: Digits

The same thing happens with digits, and it is easier to miss:

Azvya Education Pvt. Ltd.VLSI Mentor
digits.tcl
set x 7
puts "$x9"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
can't read "x9": no such variable

Digits are name characters, so x9 was read as one name.

6. The Dollar Sign in Ordinary Text

Here is the part most people get wrong, including anyone reasoning from memory. The intuition is "a dollar with nothing variable-like after it is just a dollar". That intuition is only half right.

It works when the next character cannot start a name:

Azvya Education Pvt. Ltd.VLSI Mentor
literal-dollar.tcl
puts "costs $ 5"
puts "price in $."
puts "ends with $"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
costs $ 5
price in $.
ends with $

A space, a dot, and the end of the text all leave the $ alone.

But a digit can be part of a name:

Azvya Education Pvt. Ltd.VLSI Mentor
dollar-digit.tcl
puts "it costs $5"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
can't read "5": no such variable

That line looks like plain English and is a Tcl error. The 5 was read as a variable name.

The fix is to escape the dollar sign, which is Chapter 2.6:

Azvya Education Pvt. Ltd.VLSI Mentor
escaped-dollar.tcl
puts "it costs \$5"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
it costs $5

7. Substitution Does Not Change the Word Count

Worth seeing once in this chapter, because it is the rule from Chapter 2.2 and it is what makes $name safe to use bare:

Azvya Education Pvt. Ltd.VLSI Mentor
one-word.tcl
proc show {args} { puts "received [llength $args] word(s)" }

set path "my report.txt"
show $path
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
received 1 word(s)

The value holds a space; the command still got one argument. You do not have to quote a variable to protect it.

8. Common Mistakes

Letting the name run on. "$units" when you meant "${unit}s". The error names a variable you never created, which is the clue.

Unescaped dollar signs in text. "$5" is a variable reference. §6.

Using ${} everywhere. It works, but it adds noise. Use it where the boundary is genuinely ambiguous.

Expecting $ to work inside braces. It does not — braces stop substitution. That is Chapter 2.8, and it is deliberate rather than a limitation.

9. Exercises

Exercise 1 — predict the boundary. With set base report, write down what each line prints, then check:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
puts "$base"
puts "$base.txt"
puts "$base_final"
puts "${base}_final"
puts "$base-final"

One of these is an error. Which, and why?

Exercise 2 — fix a price. Make this line print Total: $42 exactly:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
puts "Total: $42"

Exercise 3 — two ways to join. With set prefix core, produce the text core_backup twice: once using ${...}, and once by building it with a separate set. Which reads better to you, and would your answer change if the prefix were used ten times in one line?

Exercise 4 — read the error backwards. You see can't read "logfile2": no such variable, and you know a variable called logfile exists. What does the source line probably look like, and what is the one-character fix?

10. Remember

  • $name substitutes the value stored under that name.
  • The name is letters, digits and underscores, and it ends at the first character that is not one of those.
  • ${name} exists to end a name early, for when the next character would otherwise join it.
  • A dollar followed by a letter, digit or underscore is a variable reference — including $5. Escape it as \$ when you mean a literal dollar.
  • A dollar followed by a space, punctuation, or end of text is just a dollar.
  • Substituting a value never changes the word count, so a bare $name is safe even when the value contains spaces.
  • Braces stop substitution entirely. Chapter 2.8.

Next: the brackets, which run a command and use what it returns.

Where this fits

Part of the Tcl curriculum.