:TITLE: Textual Comparison - switch
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl/Tcl7.lsn,v 1.1.1.1 2007/09/15 13:30:24 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# See file "NOTICE" for licensing terms.
;#
:LESSON_TEXT_START_LEVEL 0:
<P>
<B>switch</B> <I>string pattern1 body1 ?pattern2 body2?...?patternN bodyN?</I>
   <P>- or -<P>
<B>switch</B> <I>string { pattern1 body1 ?pattern2 body2?...?patternN bodyN? }</I>
<P>
The switch command compares the argument <I>string</I> to each of the
<I>pattern</I> arguments in order.  When a <I>pattern</I> matches
<I>string</I>body argument is evaluated by the Tcl interpreter
and the result of that evaluation is returned as the return of the <B>switch</B>
command.
<P>
The switch command stops comparing <I>string</I> and <I>pattern</I> arguments
as soon as it finds one that matches.  It will match only one <I>pattern</I>
to a <I>string</I>.
<P>
If the last pattern argument to the switch command is the string <B>default</B>
then it will match any string
that was not previously matched.  If no pattern argument matches the string
and no default is given, then the switch command returns an empty
string. 
<P>
:TEXT_END:
<P>
:LESSON_TEXT_START_LEVEL 1:
The switch command allows you to choose one of several options in your
code based on the contents of a string.  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.
<P>
  The syntax of the command is:
<P>
<B>switch</B> <I>string pattern1 body1 ?pattern2 body2?...?patternN bodyN?</I>
   <P>- or -<P>
<B>switch</B> <I>string { pattern1 body1 ?pattern2 body2?...?patternN bodyN? }</I>
<P>

<I>String</I> is the string that you wish to test, and <I>pattern1,
pattern2, etc</I> are the patterns that the string will be compared to. 
If <I>string</I> matches a pattern, then the code within the
<I>body</I> associated with that pattern will be executed.  The return
from the <I>body</I> will be returned as the return of the switch statement,
and the switch command will be completed.  Only one pattern will be matched. 
<P>
If the last <I>pattern</I> argument is the string <B>default</B>, that pattern
will match to any string.  This guarantees that some set of code will be
executed no matter what the contents of <I>string</I> are.
<P>
If there is no <B>default</B> argument, and none of the <I>patterns</I> 
match <I>string</I>, then the <B>switch</B> command will return an empty
string.
<P>
If you use the brace version of this command, there will be no
substitutions done on the patterns.  The body of the command, however, will
be parsed and evaluated just like any other command, so there will be a 
pass of substitutions done on that, just as will be done in the first
syntax.  The advantage of the second form is that you can write multiple
line commands more readably with the brackets.
<P>
Note that you can use braces to group the <I>body</I> argument when using
the <B>switch</B> or <B>if</B> commands.  This is because these
commands pass their <I>body</I> argument to the Tcl interpreter for 
evaluation.  This evaluation includes a pass of substitutions just as it
does for code not within a command <I>body</I> argument.
<P>
If you haven't already run the example, do so, then try changing the
string assigned to x from
<CODE>ONE</CODE> to <CODE>TWO</CODE> and running it again.
<P>
:TEXT_END:
<P>
:LESSON_TEXT_START_LEVEL 2:
When you are writing a program you sometimes want to choose one set of code
to execute instead of another.  One of the commands you can use to select
which set of code to execute is the <B>switch</B> command. 
<P>
The switch command allows you to choose one of several options in your
code based on a string.  The string
will be compared to a set of patterns, and when the string matches a
pattern, the code associated with that pattern will be
evaluated.
<P>
The syntax of the switch command is:
<P>
<B>switch</B> <I>string pattern1 body1 ?pattern2 body2?...?patternN bodyN?</I>
   <P>- or -<P>
<B>switch</B> <I>string { pattern1 body1 ?pattern2 body2?...?patternN bodyN? }</I>
<P>

<I>String</I> is the string that you wish to compare to various
patterns, and <I>pattern1</I> is the first pattern that the string
will be compared to.  If <I>string</I> matches <I>pattern1</I>, then the
code within <I>body1</I> will be executed, and the value returned by <I>body1</I>
will be the return of the switch command.  
<P>
If <I>pattern1</I> does not match
<I>string</I>, then <I>pattern2</I> will be checked, and so forth
until either a pattern matches the string, or 
there are no more patterns.  When a pattern matches <I>string</I>,
then the switch command is complete, and the next line is executed. 
Only one pattern in a switch command will be matched. 
<P>
If the last <I>pattern</I> argument is the string <B>default</B>, that pattern
will match to any string.  This guarantees that some set of code will be
executed no matter what the contents of <I>string</I> are.
<P>
If there is no <B>default</B> argument, and none of the <I>patterns</I> 
match <I>string</I>, then the <B>switch</B> command will return an empty
string.
<P>
The switch command comes in two flavors.  Every pattern and body can be
passed to the command as a separate argument (the first form), or they
can all be grouped within brackets into one argument.  If they are
grouped into a single unit, the switch command will separate them into
patterns and bodies, but it will not perform any variable substitutions
on the patterns.
<P>
When a <I>pattern</I> matches the <I>string</I> the <I>body</I> argument
will be evaluated by the Tcl interpreter just like any other line of code.
If the body is grouped with braces, the braces will be stripped off before
the evaluation occurs, allowing substitution to occur.
<P>
If you haven't already run the example, do so, then try changing the
string assigned to x from
<CODE>ONE</CODE> to <CODE>TWO</CODE> and running it again.
:TEXT_END:

:CODE_START:
;# Set the variables we'll be comparing
set x "ONE";
set y 1;
set z "ONE";


;# This is legal
switch $x "ONE" "puts ONE=1" "TWO" "puts TWO=2" "default" "puts NO_MATCH"

;# This is more readable, the patterns are to the left, and the body
;#             associated with each pattern is to its right.
switch $x \
  "ONE" 	"puts ONE=1"  \
  "TWO" 	"puts TWO=2" \
  "default" 	"puts NO_MATCH";

;# These two examples show the difference between using the un-braced and
;#   braced versions of the switch command.
;# You can also see how a switch command can become too complex to 
;#   be written on a single line.

;# This form allows substitution in the pattern arguments.

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 does not match any of these choices";}

;# This form of the command disables variable substitution in the pattern

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"}
  }

:TEXT_END:


