if {$a < $b} { cmd_1 cmd_2 }Hinweis: Die Zeilenstruktur muß genauso übernommen werden.
if expression body [else body]Die if-Anweisung besteht aus 3 oder 5 Argumenten. Enthält eines der Argumente Leerzeichen, ist eine Gruppierung erforderlich (mittels " " oder wie oben im Beispiel). Auch müssen alle Argumente auf einer Zeile stehen, es sei denn, die Zeilenschaltung erfolgt innerhalb einer Gruppierung.
Der Ausdruck wird durch einen internen exp-Aufruf ausgewertet, i.e. trotz geschweifter Klammern erfolgt die $- und []-Auflösung. Ebenso erfolgt für die Bodies ein zweiter Auflösungsschritt (mittels eval), so daß immer geschweifte Klammern genutzt werden können.
Ist der Wert von expression ungleich 0, bedeutet das den booleschen Wert true, 0 dagegen false.
Beispiel:
set jahr 1999 if {$jahr % 4 == 0 && ($jahr % 100 != 0 || $jahr % 400 == 0)} { puts "Schaltjahr" } else { puts "Kein Schaltjahr" }Die Position der geschweiften Klammern ist wichtig: So muß die öffnende Klammer des then-Zweiges noch auf der gleichen Zeile wie if stehen, dann kommt jedes Kommando auf eine eigene Zeile. Die schließende Klammer des if-Zweiges, das Wort else und die öffnende Klammer des else-Zweiges müssen ebenfalls gemeinsam auf einer Zeile stehen. Das erste Kommando nach der if-Anweisung kommt auf eine neue Zeile.
Für geschachtelte if-Anweisungen existiert zur Vereinfachung der
Schreibweise das Schlüsselwort elseif
:
if {$cmd == "add"} { ... } elseif {$cmd == "del"} { ... } else { ... }Für Mehrfachverzweigungen benutzt man die switch-Anweisung:
switch flags value { pat1 body1 pat2 body2 ... }Der Wert wird der Reihe nach mit den angegebenen Patterns verglichen und der zugehörige Body ausgeführt. Das Pattern
default
paßt immer,
muß aber das letzte Pattern sein. Im Gegensatz zu den meisten
Programmiersprachen arbeitet switch auch mit Strings:
switch $tag { Montag {set tagnr 1} Dienstag {set tagnr 2} ... Sonnabend - Samstag {set tagnr 6} Sonntag {set tagnr 0} default {set tagnr -1} }Durch Flags kann gesteuert werden, was Übereinstimmung bedeutet (global style pattern matching, exact oder reguläre Ausdrücke).
while expression body for initialisierung expression reinit bodyWichtig ist hier, daß expression und reinit unbedingt in geschweifte Klammern (und nicht in Hochkommas) eingeschlossen werden. Die Auswertung erfolgt sonst vor der Ausführung der Schleifenanweisung, diese erhält statt der Ausdrücke u.U. schon feste Werte zugewiesen, statt die Auswertung bei jedem Durchlauf selbst zu machen. Das passiert z.B. dann, wenn der Testausdruck einfach eine Variable ist.
# Beispiel while-Schleife set betrag 1000 set zinssatz 0.03 set jahr 0 while {$betrag < 2000} { set betrag [expr $betrag*(1+$zinssatz)] incr jahr # jahr wird um 1 erhöht, hier ohne $ schreiben } puts "$jahr $betrag" # Beispiel for-Schleife for {set i 0} {$i < 20} {incr i} { puts "$i: [expr sqrt($i)]" }Eine weitere praktische Schleife läßt eine Variable über eine vorgegebene Liste (s.u.) von Werten laufen:
foreach tag {Montag Dienstag Mittwoch Donnerstag Freitag} { puts "Am $tag muß ich zeitig aufstehen :-(" }Die Liste kann auch in einer Variable gespeichert sein, oder man kann so alle Elemente eines assoziativen Array abarbeiten (s.u.).
procwird eine neue Prozedur (Funktion) definiert:
proc name argumente bodyDie Argumente werden durch Leerzeichen getrennt und mit {} gruppiert. Der Body enthält meist eine return-Anweisung für die Rückgabe eines Wertes:
proc umfang {r} { set u [expr 2*$r*3.1416] return $u }Diese Prozedur kann nach ihrer Definition genutzt werden:
puts "Umfang bei Radius 4: [umfang 4]"Ein etwas umfangreicheres Beispiel zur Berechnung des Zinseszins bei festem Zinssatz:
proc zins {betrag zinssatz laufzeit} { set j 1 while {$j <= $laufzeit} { set zinsen [expr $betrag*$zinssatz] set betrag [expr $betrag+$zinsen] set j [expr $j+1] } return $zinsen }Um Prozeduren nicht immer interaktiv eingeben zu müssen, ist es sinnvoll, diese in einer Datei abzulegen und diese Datei einzubinden:
source scriptfileAlle Variablen in Prozeduren sind lokal, Parameter werden immer als Werte übergeben. Der Zugriff auf globale Variablen sowie die Parameterübergabe als Referenz sind durch spezielle Befehle möglich.
after millisec commandDas Kommando ist meist eine Prozedur. Enthält sie als letzte Zeile den gleichen after-Befehl, erfolgt eine periodische Ausführung. Das funktioniert aber nur solange, wie der Tcl-Interpreter läuft. Besonders bei Scriptfiles muß eine vorzeitige Beendigung verhindert werden.
Zum Warten auf Ereignisse existiert der Befehl
vwait variableDamit wartet das Programm, bis sich der Wert der angegeben Variable ändert. Das kann durch einen mit after verzögerten Befehl oder durch einen Befehl, der durch ein Datei- bzw. Netzereignis ausgelöst wird, erfolgen.
Wird die Variable nie verändert, wartet das Programm ewig und arbeitet nur Ereignisroutinen ab (z.B. als Dämon).