Tcl Part I · Module 5 · Strings
append: Building a String Piece by Piece
Everything else in this module hands you a new string and leaves your variable alone. This command is the exception: it adds text to the end of a variable, in place. That makes it the natural way to assemble a report or a message from parts, and it is also genuinely cheaper than the obvious alternative of reassigning the variable each time — a difference that does not matter for three lines and matters a great deal once you are building something from a thousand.
Foundation9 min readTclPart IStringsappendBuilding Output
Part I · Module 5 · Chapter 5.10 · append: Building a String Piece by Piece
1. The Command
set report ""
append report "Summary\n"
append report "--------\n"
puts -nonewline $reportSummary
--------append takes a variable name — no $ — and adds text to the end of what it holds. Same shape as set and incr.
Note it is not string append. Along with format, scan, split and join, it is a command in its own right — Chapter 5.1 §3.
2. It Modifies the Variable
This is what makes it different from everything else in the module:
set s "hello"
string toupper $s
puts "after string toupper: $s"
append s " world"
puts "after append: $s"after string toupper: hello
after append: hello worldstring toupper returned a value that was discarded. append changed s directly.
Chapter 5.1 §7 said nothing in string modifies its argument. append is not in string, and it does.
3. Several Pieces at Once
set report ""
set n 3
append report "rows: " $n "\n"
puts -nonewline $reportrows: 3Three arguments, joined end to end with nothing between them. That is often tidier than building a quoted string with substitutions in it, especially when the pieces come from different places.
Both forms are fine:
set a ""
set b ""
set n 3
append a "rows: " $n "\n"
append b "rows: $n\n"
puts "identical: [expr {$a eq $b}]"identical: 14. It Creates the Variable
append fresh "first piece"
puts $freshfirst pieceNo set fresh "" was needed. Like incr in Chapter 3.9 §4, append treats a missing variable as empty and creates it.
And like incr, that convenience hides typos — a misspelled variable name quietly starts a second string rather than failing. Initialising with set report "" first is still worth the line, because it says plainly where the building starts.
5. It Returns the New Value
set s "a"
puts "append returns: [append s "b"]"
puts "s is now: $s"append returns: ab
s is now: abOccasionally useful; mostly you call it for its effect and ignore the result.
6. Why Not Just Use set
This does the same thing:
set report ""
set report "$report Summary"
set report "$report --------"
puts $report Summary --------It works, and append is better for two reasons.
It reads better. append report "Summary" says "add this". set report "$report Summary" makes you read the whole line to notice that report appears on both sides.
It is cheaper. The set form builds an entirely new string every time — copying everything already there, then adding the new piece. append can extend what is already in the variable.
For three lines that difference is invisible. For a report assembled from thousands of pieces it is the difference between a script that finishes and one that appears to hang, because the set version does work proportional to the square of the output size.
7. Building a Report
The shape you will actually write:
set report ""
append report "Run Summary\n"
append report "===========\n"
append report "passed: " 18 "\n"
append report "failed: " 2 "\n"
append report "===========\n"
puts -nonewline $reportRun Summary
===========
passed: 18
failed: 2
===========Three parts: initialise to empty, append as you go, output once at the end.
Building the whole thing before printing — rather than puts-ing each line as you compute it — means you can write it to a file, return it from a procedure, or measure its length before deciding what to do with it.
Once you reach Module 9 the middle section will be a loop, and the shape will be identical.
8. There Is Also lappend
A neighbour worth knowing exists, since the names are similar:
set items {}
lappend items "first"
lappend items "second"
puts "as a list: $items"
puts "elements: [llength $items]"as a list: first second
elements: 2append adds characters to a string. lappend adds elements to a list. Module 6 covers it.
If you are building something that will be taken apart again later, you probably want a list. If you are building text to print, you want append.
9. Common Mistakes
Writing append $report "text". The name goes in without a $.
Looking for string append. It is not a string subcommand. §1.
Using set x "$x ..." in a loop. §6.
Forgetting to initialise. It works, but a typo then silently builds a second variable. §4.
Using puts on text that already ends in a newline. §7.
Building a list with append. Use lappend. §8.
10. Exercises
Exercise 1 — three pieces. Build the text one-two-three in a variable using three append calls, then print it.
Exercise 2 — several arguments. Build "count: 7 items" with a single append taking several arguments, with the 7 coming from a variable.
Exercise 3 — in place or not. Show, in four lines, that string toupper leaves a variable unchanged while append changes it.
Exercise 4 — a small report. Build a three-line report with a heading, a separator and one data line, then print it once with puts -nonewline. Then print it with plain puts and explain the difference.
Exercise 5 — the set version. Write the same report using set x "$x ..." instead. Which is easier to read? Which would you expect to be slower, and why?
Exercise 6 — append or lappend. For each, say which: building a comma-separated line for a file; collecting filenames to process later; assembling a multi-line message; gathering values to sort.
11. Remember
append varname textadds to the end of a variable, in place. No$on the name.- It is not a
stringsubcommand — it is its own command. - It is the one thing in this module that modifies a variable rather than returning a new value.
- It accepts several values in one call, joined with nothing between them.
- It creates the variable if it does not exist, and returns the new value.
- Initialise with
set x ""anyway, so a typo cannot quietly start a second string. - Prefer it to
set x "$x ..."— clearer, and it avoids rebuilding the whole string each time. - Build the whole text, then output once.
lappendis the list equivalent.
Next: controlling exactly how a value appears.
Where this fits
Part of the Tcl curriculum.
