-->
Page 512
Adding an else clause to an if statement is done as follows:
if {$x <= 0} { set x 10; } else { set x 0; }
You can also add as many elseif statements as desired:
if {$x == 0} { set x 10; } elseif {$x == 10} { incr x -1; } elseif {$x == 100} { set x 50; } else { set x 0; }
In many cases, adding extra elseif statements becomes cumbersome and difficult to understand. To provide a more compact way of expressing the same logic, tcl implements the switch command. switch works by associating a value (string or number) with a block. The preceding if statement, when written as a switch statement, becomes
switch $x { 0 {set x 10;} 10 {incr x -1;} 100 {set x 50;} }
By default, only the block corresponding to the matched value will be executed, but a switch statement can implement "fallthrough" if the block is designated as a single minus sign (-). The switch statement
switch $x { 0 - 10 - 100 {incr x -1} }
is equivalent to the following if statement:
if { ($x == 0) || ($x == 10) || ($x == 100) } { incr x -1; }
tcl provides three loop commands:
Page 513
tcl also provides two loop control commands:
The while loop executes its body while its test condition is true. The structure can be thought of as
while {condition} {block}
The following is a simple while loop that counts to ten:
set x 0; while {$x < 10} { incr x; puts $x; }
The foreach loop iterates over a set of arguments and executes its body each time. The foreach loop has the following structure:
foreach variable {items} {block}
variable is the name of the variable to which each item in the set items will be assigned in turn. Here is an example:
foreach element {o c n p li} { switch $element { o - n {puts gas;} c - p - li {puts solid;} } }
In this case, the list of items to check is specified, but a variable can be used also:
set elements "o c n p li"; foreach element $elements { switch $element { o - n {puts gas;} c - p - li {puts solid;} } }
If a variable instead of a list of items is given, the braces should not be used because the braces will be treated as braces used for quoting.
The for loop allows for the most control while looping. It can be broken down as
for {initialization} {condition} {increment} {body}
Page 514
A simple for loop example that counts to 10 is
for {set i 0} {$i <= 10} {incr i} { puts $i; }
You have seen simple initialization statements, but the initialization and increment parts of the for loop can be as complicated as required.
Now for a look at the loop control commands, break and continue. The break command breaks out of loop and executes the next line of code after the loop's block, while the continue command skips to the next iteration of the loop.
The continue command is really handy for reading in initialization files where comments lines need to be allowed. If the following statement is included in a loop that reads in a file
if { [regexp {^#} [string trim $line] ]} {continue;}
all lines that start with a pound sign (#) will be skipped.
tcl provides a simple and effective method for file input and output similar to the methods in the C standard I/O library. The first step in file I/O is to open a file and get a file handle or file ID. As an example, the command
set f [ open /etc/passwd r];
opens the file /etc/passwd with mode r and returns a file handle that is assigned to the variable f. tcl supports the following file open modes:
r | Open for reading only; the file must exist. |
r+ | Open for reading and writing; the file must exist. |
w | Open for writing; the file will be created if it does not exist; otherwise, it is truncated. |
w+ | Same as w; expect that the file is opened for reading also. |
a | Open the file for appending text; the file will be created if it does not exist. |
a+ | Same as a, except that the file is opened for reading also. |
The open command can also be overloaded to run subprocesses with more control than the exec command provides. To open a process instead of a file, the filename is replaced with a brace-quoted string beginning with a pipe character (|) and containing the command to run. For example, the following command opens a ps for reading:
set f [ open {| ps } r ];
For processes opened in this manner, the tcl command pid returns the process ID of the file handle associated with a process. For the preceding example,
pid $f