Skip to content
VLSI Mentor

Tcl Part I · Module 5 · Strings

The string Command and Its Subcommands

Most of the work a real script does is text handling, and Tcl puts almost all of it behind a single command. That is unusual enough to be worth a short chapter on its own, because it changes how you look things up: there is no object with methods to explore, there is one command whose first argument says what you want done. This chapter maps the whole set, shows you how to ask the interpreter for the list rather than reaching for documentation, and flags the one thing that catches people out — which argument goes first.

Foundation10 min readTclPart IStringsReference

Part I · Module 5 · Chapter 5.1 · The string Command and Its Subcommands

1. One Command, Many Jobs

Azvya Education Pvt. Ltd.VLSI Mentor
shape.tcl
set s "  Report Draft  "

puts "length   -> [string length $s]"
puts "toupper  -> [string toupper $s]"
puts "trim     -> <[string trim $s]>"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
length   -> 16
toupper  ->   REPORT DRAFT  
trim     -> <Report Draft>

Three different operations, one command name. The second word — length, toupper, trim — says which one.

2. Why It Looks Like That

In Python you would write s.upper(): the data first, then the operation. In Tcl the command name always comes first, because Chapter 2.1 established that every line is a command followed by its words. There is no object to hang a method on.

So string is a command that dispatches on its first argument:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
string  toupper  $s
   │       │      │
   │       │      └── the data
   │       └───────── which operation
   └───────────────── the command

Tcl calls this shape an ensemble — one command name grouping related operations. You have already met others: file, info, and clock all work the same way. Recognising the shape means you can guess at file and info without being taught them.

3. The Whole Set

Grouped by what they do, with the chapter that covers each:

SubcommandWhat it doesChapter
lengthhow many characters5.2
indexone character at a position5.3
rangea span of characters5.3
first lastposition of a substring5.4
matchtest against a glob pattern5.5
equal comparecompare two strings5.6
toupper tolower totitlechange case5.7
trim trimleft trimrightremove edge characters5.8
replace mapsubstitute text5.9
istest what a value looks like3.5
repeatrepeat a stringthis chapter, §6
reversereverse a stringthis chapter, §6
wordstart wordendword boundaries around a positionrarely needed
bytelengthstorage size in bytes5.2

Two things in this module are not string subcommands, which is worth knowing now so you do not go looking: append, format, scan, split and join are commands in their own right. They get chapters 5.10 to 5.13.

4. Ask the Interpreter

Do not memorise that table. Ask for it:

Azvya Education Pvt. Ltd.VLSI Mentor
discover.tcl
puts [catch {string bogus x} message]
puts $message
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
1
unknown or ambiguous subcommand "bogus": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart

Deliberately use a subcommand that does not exist, and Tcl lists every one that does.

This is faster than opening documentation and it is always right for the interpreter you are actually running. It works on every ensemble command:

Azvya Education Pvt. Ltd.VLSI Mentor
discover-more.tcl
catch {file bogus} m
puts "file:  [string range $m 0 70]..."
catch {info bogus} m
puts "info:  [string range $m 0 70]..."
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
file:  bad option "bogus": must be atime, attributes, channels, copy, delete, ...
info:  unknown or ambiguous subcommand "bogus": must be args, body, cmdcount, ...

The exact wording differs between commands — some say bad option, others unknown or ambiguous subcommand — but every one of them lists what it does accept.

5. Which Argument Goes First

The one genuine inconsistency, and the reason the usage line matters.

Most subcommands take the string first:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
string length   $text
string toupper  $text
string range    $text 0 5

But the searching and matching ones do not:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
string first  ":" $text        ;# what to find, then where to look
string match  "*.txt" $text    ;# the pattern, then the string

string first takes the needle before the haystack, and string match takes the pattern before the subject. If a search is returning -1 when you are sure the text is there, check the argument order before anything else.

The fix is not memorisation. It is the usage line:

Azvya Education Pvt. Ltd.VLSI Mentor
usage.tcl
catch {string first} m ; puts $m
catch {string match} m ; puts $m
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
wrong # args: should be "string first needleString haystackString ?startIndex?"
wrong # args: should be "string match ?-nocase? pattern string"

Tcl names the arguments for you — needleString, haystackString, pattern, string.

6. Two Small Ones With No Chapter

Azvya Education Pvt. Ltd.VLSI Mentor
small.tcl
puts [string repeat "-" 20]
puts [string repeat "ab" 3]
puts [string reverse "stressed"]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
--------------------
ababab
desserts

string repeat is genuinely useful for separator lines in reports. string reverse comes up rarely, and mostly in puzzles.

7. Everything Returns a New String

No string subcommand changes its argument:

Azvya Education Pvt. Ltd.VLSI Mentor
immutable.tcl
set s "hello"

string toupper $s
puts "after toupper: $s"

set s [string toupper $s]
puts "after assigning: $s"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
after toupper: hello
after assigning: HELLO

The first string toupper computed HELLO, returned it, and the script discarded it — Chapter 1.5 §3. To keep a result you must store it.

The one exception in this module is append, which does modify a variable — Chapter 5.10.

8. Common Mistakes

Looking for a method on the string. There is no object. The command comes first.

Forgetting to store the result. §7. Nothing is modified in place.

Getting the argument order wrong on first and match. §5. Read the usage line.

Memorising the subcommand list. §4. Ask for it.

Expecting split or format to be string subcommands. They are separate commands. §3.

9. Exercises

Exercise 1 — get the list. Run string bogus and read the subcommands. Pick three you have not seen and guess what they do, then check with the usage-line trick.

Exercise 2 — three operations. On the text " Draft Report ", produce its length, an uppercase version, and a trimmed version — storing each result.

Exercise 3 — argument order. Without running, write the correct call for: finding the position of "-" in a variable name; testing whether name ends in .log. Then check both with the usage lines.

Exercise 4 — the discovery habit elsewhere. Use the same trick on clock and on info. How many subcommands does each have?

Exercise 5 — a separator line. Print a 40-character line of =, then a heading, then the line again, using string repeat.

Exercise 6 — prove nothing changes. Write three lines that show a string subcommand leaving its input untouched, then the version that keeps the result.

10. Remember

  • string is one command with about twenty subcommands, not methods on an object.
  • The operation comes second: string toupper $text.
  • This shape is called an ensemble, and file, info and clock work the same way.
  • Ask for the subcommand list with a deliberately wrong one: string bogus.
  • Ask for a subcommand's arguments by calling it with none.
  • string first and string match take the needle or pattern first. Check this before debugging anything else.
  • Nothing is modified in place. Store the result.
  • append, format, scan, split and join are separate commands, covered later in this module.

Next: the simplest subcommand, and the one question it raises about what a character is.

Where this fits

Part of the Tcl curriculum.