Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 6.  Control Structure Commands


The switch command is used to branch to one of many command bodies depending on the value of an expression. The choice can be made on the basis of pattern matching as well as simple comparisons. Pattern matching is discussed in more detail in Chapter 4 and Chapter 11. The general form of the command is:

switch flags value pat1 body1 pat2 body2 ...

Any number of pattern-body pairs can be specified. If multiple patterns match, only the body of the first matching pattern is evaluated. You can also group all the pattern-body pairs into one argument:

switch flags value {pat1 body1 pat2 body2 ... }

The first form allows substitutions on the patterns but will require backslashes to continue the command onto multiple lines. This is shown in Example 6-4 on page 72. The second form groups all the patterns and bodies into one argument. This makes it easy to group the whole command without worrying about newlines, but it suppresses any substitutions on the patterns. This is shown in Example 6-3. In either case, you should always group the command bodies with curly braces so that substitution occurs only on the body with the pattern that matches the value.

There are four possible flags that determine how value is matched.

-exactMatches the value exactly to one of the patterns. This is the default.
-globUses glob-style pattern matching. See page 48.
-regexpUses regular expression pattern matching. See page 134.
--No flag (or end of flags). Necessary when value can begin with -.

The switch command raises an error if any other flag is specified or if the value begins with -. In practice I always use the -- flag before value so that I don't have to worry about that problem.

If the pattern associated with the last body is default, then this command body is executed if no other patterns match. The default keyword works only on the last pattern-body pair. If you use the default pattern on an earlier body, it will be treated as a pattern to match the literal string default:

Example 6-3 Using switch for an exact match.
switch -exact -- $value {
   foo { doFoo; incr count(foo) }
   bar { doBar; return $count(foo)}
   default { incr count(other) }

If you have variable references or backslash sequences in the patterns, then you cannot use braces around all the pattern-body pairs. You must use backslashes to escape the newlines in the command:

Example 6-4 Using switch with substitutions in the patterns.
switch -regexp -- $value \
   ^$key { body1 }\
   \t### { body2 }\
   {[0-9]*} { body3 }

In this example, the first and second patterns have substitutions performed to replace $key with its value and \t with a tab character. The third pattern is quoted with curly braces to prevent command substitution; square brackets are part of the regular expression syntax, too. (See page Chapter 11.)

If the body associated with a pattern is just a dash, -, then the switch command "falls through" to the body associated with the next pattern. You can tie together any number of patterns in this manner.

Example 6-5 A switch with "fall through" cases.
switch -glob -- $value {
   X* -
   Y* { takeXorYaction $value }

Comments in switch Commands


A comment can occur only where the Tcl parser expects a command to begin. This restricts the location of comments in a switch command. You must put them inside the command body associated with a pattern, as shown in Example 6-6. If you put a comment at the same level as the patterns, the switch command will try to interpret the comment as one or more pattern-body pairs.

Example 6-6 Comments in switch commands.
switch -- $value {
   # this comment confuses switch
   pattern { # this comment is ok }

      Previous section   Next section