Tcl Tutorial Lesson 8

Difference between version 10 and 13 - Previous - Next
**Textual Comparison - switch**


!!!!!!
'''[Tcl Tutorial Lesson 7%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 9%|%Next lesson%|%]'''
!!!!!!



The `switch` command allows you to choose one of several options in your code.  It is similar to `switch` in C, except that it is more flexible, because you can switch on strings, instead of just integers.  The string will be compared to a set of patterns, and when a pattern matches the string, the code associated with that pattern will be evaluated.

It's a good idea to use the `switch` command when you want to match a variable against several possible values, and don't want to do a long series of `if... elseif ... elseif` statements.

The syntax of the command is:

======
   switch ?options? string {
       pattern1 {
           body1
       }
       ?pattern2 {
           body2
       }?
       ...
       ?patternN {
           bodyN
       }?
   }
======

`string` is the string that you wish to test, and `pattern1, pattern2,` etc are the patterns that the string will be compared to.  If `string` matches a pattern, then the code within the `body` associated with that pattern will be executed.  The return value of the `body` will be returned as the return value of the switch statement.  Only one pattern will be matched.

If the last `pattern` argument is the string `default`, that pattern will match any string.  This guarantees that some set of code will be executed no matter what the contents of `string` are.

If there is no `default` argument, and none of the `patterns` match `string`, then the `switch` command will return an empty string.

If the body is a dash (`-`), then the `switch` command uses the body of the next pattern, i.e. it "falls through":

======
set string "a"
switch $string {
    "a" -
    "b" {
        puts "Using the body for pattern 'b' for both a and b"
    }
}
====== 
The `options` can be used to change the interpretation of the patterns. By default ''glob-style pattern matching'' is used, where an asterisk (*) matches any number of characters, that is, a pattern "lesson*" matches "lesson", "lessons", "lession 2" etc.
Other options are: `-exact`, causing the patterns to be literal strings and `-regexp`, in which case the patterns follow the rules of ''regular expressions'' (see [Tcl Tutorial Lesson 20%|%Regular Expressions 101%|%]).
***Alternative Syntax***

The `switch` command supports a rarely-used alternative syntax in which the patterns and script bodies are each separate arguments to the `switch` command rather than grouped together into a single list argument.  This can be useful if the patterns or scripts are the products of substitution, which would otherwise not be applied due to the list typically being brace-quoted.  However, be aware of the need for line continuation backslashes when the newlines are not themselves quoted by braces.

======
   switch ?options? string\
       pattern1 {
           body1
       }\
       ?pattern2 {
           body2
       }?\
       ...\
       ?patternN {
           bodyN
       }?
======

----

***Examples***
****Example 1****

A first example, classify a polygon:
======
# Name polygons, based on the number of edges.

set edge_count 3

switch $edge_count {
    0 -
    1 -
    2 {
        puts "Not a polygon."
    }
    3 {
        puts "This is a triangle."
    }
    4 {
        puts "This is a quadrilateral."
    }
    5 {
        puts "This is a pentagon."
    }
    default {
        puts "Unknown polygon."
    }
}
======
<<discussion>> Resulting output
======
This is a triangle.
======
<<enddiscussion>>
****Example 2****
Here is a second example, showing that braces do not honour variable substitutions (note: consistent behaviour):

======
set x ONE
set y 1
set z ONE

# Note that patterns are not subject to substitutions if
# contained in braces

switch $x {
    $z {
        set y1 [expr {$y+1}]
        puts "MATCH \$z. $y + $z is $y1"
    }
    ONE {
        set y1 [expr {$y+1}]
        puts "MATCH ONE. $y + one is $y1"
    }
    TWO {
        set y1 [expr {$y+2}]
        puts "MATCH TWO. $y + two is $y1"
    }
    THREE {
        set y1 [expr {$y+3}]
        puts "MATCH THREE. $y + three is $y1"
    }
    default {
        puts "$x is NOT A MATCH"
    }
}
======

<<discussion>> Resulting output
======
MATCH ONE. 1 + one is 2
======
<<enddiscussion>>
****Example 3****

Here is a third example derived from the above, showing variable substitutions in action when braces are not used:

======
set x ONE
set y 1
set z ONE

switch $x\
    $z {
        set y1 [expr {$y+1}]
        puts "MATCH \$z. $y + $z is $y1"
    }\
    ONE {
        set y1 [expr {$y+1}]
        puts "MATCH ONE. $y + one is $y1"
    }\
    TWO {
        set y1 [expr {$y+2}]
        puts "MATCH TWO. $y + two is $y1"
    }\
    THREE {
        set y1 [expr {$y+3}]
        puts "MATCH THREE. $y + three is $y1"
    }\
    default {
        puts "$x is NOT A MATCH"
    }
======

<<discussion>> Resulting output
======
MATCH $z. 1 + ONE is 2
======
<<enddiscussion>>

!!!!!!
'''[Tcl Tutorial Lesson 7%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 9%|%Next lesson%|%]'''
!!!!!!