40.2.3.5 Control Flow

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.