Tcl has the four usual classes of control flow found in most other programming languages:
if...elseif...else, while, for, foreach, switch, and eval.
We go through each in turn.
The general form of an if
command is the following:
if test1 body1 ?elseif test2 body2 elseif ...? ?else bodyn?
which when evaluated, evaluates expression test1, which if true
causes body1 to be evaluated, but if false, causes test2 to
be evaluated, and so on. If there is a final else
clause
then its bodyn part is evaluated if all of the preceding tests
failed. The return result of an if
statement is the result of
the last body command evaluated, or the empty list if none of the
bodies are evaluated.
Conditional looping is done through the while
command:
while test body
which evaluates expression test, which if true then evaluates body. It continues to do that until test evaluates to 0, and returns the empty string.
A simple example is:
set a 10 while {$a > 0} { puts $a; incr a -1 }
which initializes variable a
with value ten and then
loops printing out the value of a
and decrementing it until
its value is 0, when the loop terminates.
The for
loop has the following form:
for init test reinit body
which initializes the loop by executing init, then
each time around the loop the expression test is evaluated,
which if true causes body to be executed and then executes
reinit. The loop spins around until test evaluates to 0.
The return result of a for
loop is the empty string.
An example of a for
loop:
for {set a 10} ($a>0) {incr a -1} {puts $a}
which initializes the variable a
with value 10
, then
goes around the loop printing the value of a
and decrementing it
as long as its value is greater than 0
.
Once it reaches 0
the loop terminates.
The foreach
command has the following form:
foreach varName list body
where varName is the name of a variable, list is an instance
of a list, and body is a series of commands to evaluate. A
foreach
then iterates over the elements of a list, setting the
variable varName to the current element, and executes body.
The result of a foreach
loop is always the empty string.
An example of a foreach
loop:
foreach friend {joe mary john wilbert} {puts "I like $friend"}
will produce the output:
I like joe I like mary I like john I like wilbert
There are also a couple of commands for controlling the flow of loops:
continue
and break
.
continue
stops the current evaluation of the body of a loop and
goes on to the next one.
break
terminates the loop altogether.
Tcl has a general switch statement, which has two forms:
switch ?options? string pattern body ?pattern body ... ? switch ?options? string { pattern body ?pattern body ...? }
When executed, the switch command matches its string argument against each of the pattern arguments, and the body of the first matching pattern is evaluated. The matching algorithm depends on the options chosen, which can be one of
-exact | use exact matching
|
-glob | use glob-style matching
|
-regexp | use regular expression matchinig
|
An example is:
set a rob switch -glob $a { a*z { puts "A to Z"} r*b { puts "rob or rab"} }
which will produce the output:
rob or rab
There are two forms of the switch
command. The second form has
the command arguments surrounded in curly brackets. This is
primarily so that multi-line switch commands can be formed, but it also
means that the arguments in brackets are not evaluated (curly
brackets suppress evaluation), whereas in the first type of switch
statement the arguments are first evaluated before the switch is
evaluated. These effects should be borne in mind when choosing which
kind of switch statement to use.
The final form of control statement is eval
:
eval arg ?arg ...?
which takes one or more arguments, concatenates them into a string, and executes the string as a command. The return result is the normal return result of the execution of the string as a command.
An example is
set a b set b 0 eval set $a 10
which results in the variable b
being set to 10
. In this
case, the return result of the eval
is 10
, the result of
executing the string "set b 10"
as a command.