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).