Tcl Control Structures

Control structures involve grouping a set of commands into a command body and executing the body either in a loop or based on some condition(s). The body of the structure is grouped with curly braces. This is important as the braces prevent the body from being substituted and evaluated until the proper time.

There are several different categories of control structure commands in Tcl. These include conditional commands, loop commands, error handling commands and low-level control commands. The following list contains some commonly used control structure commands and a summary of their usage. For more in-depth explanations and a complete listing, refer to http://www.tcl.tk/man/ or to a Tcl/T

Commonly used control structure commands

if {expression1} {body1} ? elseif? ?{expression2} {body2}? ?else? ?{body3}?
Conditionally executes body based on the evaluation of expression. The elseif and else commands are optional and used only if chained conditionals to be considered. Multiple elseif commands are allowed.
for {first} {condition} {last} {body}
The first expression initializes the loop. The condition expression is evaluated to determine if the loop continues to execute. The last expression is executed after the body in each loop.
foreach value valueList {body}
The valueList is a list variable. This command loops through each entry in valueList, sets the variable value to the value of the entry, and executes body.
catch {body} ?variable?
Used to catch errors when executing body. The value returned from body can optionally be stored in variable. Catch returns 0 if there is no error, non-zero otherwise.
break
Used to break out of a loop during execution.
continue
Used to stop the current loop iteration and continue to the next iteration.
return ?-code code? ?-errorcode errc? ?-errorinfo erri? ?value?
Return from a procedure. Optional arguments allow for specific values or error codes to be returned. By default, a procedure returns the value of the last statement executed. Useful in conjunction with catch.

The if command is the most basic conditional check. The if and elseif commands take two parameters: the conditional statement and the body of commands to execute. When the conditional expression returns non-zero, the command body is processed. Otherwise, the command in the else body is processed.

Examples

set vector_list "p1w1c1.y p1w1c2.y p1w1c3.y";
llength $vector_list;
3

if {[ llength $vector_list] == 0} {
   puts "There are no curves in the list";
} elseif {[ llength $vector_list] < 5} {
   puts "There are less than 5 curves in the list";
} else {
   puts "There are more than 5 curves in the list";
}
There are less than 5 curves in the list
Since the if command checks for 0 or non-zero as the condition, the following statement is valid for checking if the list length is zero.
if {[llength $vector_list]} {}
The for command is a handy way of looping through commands when you know how many times to loop and each loop is an increment of the last.
set number_of_curves 100;
for {set i 1} {$i <= $number_of_curves} {incr i} {
   puts "Curve = $i";
}
Curve = 1
Curve = 2
…
Curve = 100
The foreach command is very similar to the for command but foreach works with lists instead of sequential values.
set node_list "12 10 17 15 5";
foreach node $node_list {
   puts "Processing node $node";
}
Processing node 12
Processing node 10
Processing node 17
Processing node 15
Processing node 5
You can combine this with the lsort command to sort the list for looping.
foreach node [lsort -integer $node_list] {
   puts "Processing node $node";
}
Processing node 5
Processing node 10
Processing node 12
Processing node 15
Processing node 17
The catch command is important for catching errors, either from individual commands or from a value returned from a procedure.
if { [catch {command}] } {
   puts "Error";
} else {
   puts "No error";
}