Tcl
Tcl (ursprünglich "Tool command language", also etwa "Werkzeugsprache") ist eine OpenSource - Skriptsprache, die sehr einfach zu erlernen ist und mit der Applikationen innerhalb kurzer Zeit erstellt werden können. Tcl wird üblicherweise wie engl. tickle (kitzeln) ausgesprochen oder natürlich Te Ce El. Sie ist mit Unix-Shell-Sprachen verwandt. Die Syntax sieht C-ähnlich aus, aber auch starke Bezüge zu Lisp sind vorhanden.
Sehr bekannt ist Tcl durch das Tk Toolkit, mit dem sich portable grafische Benutzeroberflächen leicht programmieren lassen. Der grafische Werkzeugkasten "Tk" steht für eine Vielzahl von Betriebssystemen mit dem für die jeweiligen Fensterverwalter üblichen Aussehen ("native look and feel") zur Verfügung. Diese Programmierschnittstelle wird auch von Perl und Python benutzt. Die Kombination aus Sprache und Toolkit, auch bekannt als Tcl/Tk, ist jedoch besonders einfach zu verwenden; sie stammt von John Ousterhout (seit 1988). Tcl arbeitet standardmässig mit Unicode, so dass Zeichenketten ohne besonderen Aufwand alle Zeichen bis U+FFFD enthalten können. Über 16 bit hinausgehende Unicodes werden noch nicht unterstützt.
Syntax
Tcl ist im Grundsatz sehr einfach aufgebaut und grenzt sich gegen Sprachen wie Perl, APL und C durch absolut konsequenten Einsatz einer einheitlichen Syntax ab. Wer mit Kommandozeileninterpretern (Shell, MS-DOS) vertraut ist, kennt auch die Grundstruktur von Tcl-Kommandos. Ein Tcl-Skipt besteht aus mehreren Kommandos. Ein Kommando besteht aus einem Kommandowort gefolgt von Argumenten (Parameter). Ein Kommando wird von einem Zeilenende oder Semikolon begrenzt. Gegenüber einfachen Kommandozeileninterpretern verfügt aber Tcl über die Möglichkeit, Kommandos ineinander zu verschachteln. Statt eines Argumentes in einem Kommando, kann in eckigen Klammern ein weiteres Kommando angegeben werden. Die Unterkommandos werden zuerst ausgeführt. Ihr Resultat wird dann jeweils als Argument im übergeordneten Kommando eingesetzt.
Auch Konstrukte wie if und while, über Zuweisungen bis hin zu Kommentaren sind Kommandos. Der Kommentar ist ein Kommando, das einfach nichts tut. Die Kommandos folgen der Polnischen Notation, wie Lisp. Das Kommandowort steht am Anfang, dann folgen die Parameter.
kommandoWort par1 par2 ..parN
Ein Rückstrich (Backslash) am Ende einer Zeile markiert, dass ein Kommando auf der nächsten Zeile fortgesetzt wird.Anführungsstriche schliessen Zeichenketten ein. Damit keine Verwechslungen auftreten, sind einfache Anführungen (Hochkommata) unbekannt. Auch das einfache Gleichheitszeichen (=) kommt nicht vor. Das doppelte Gleichheitszeichen dient Vergleichen.
Geschweifte Klammern schützen ihren Inhalt von Interpretation. Dadurch können Kommandos dann auch mehrere (auch viele) Zeilen umfassen. Als Beispiel sei das While-Kommando erwähnt. Es erwartet zwei Argumente, das erste enthält einen Befehl, der die Bedingung repräsentiert, das zweite die auszuführenden Kommandos innerhalb der While-Schleife.
while { einTclKommando } { FolgeVonTclKommandos }
Die geschweiften Klammern schützen den Inhalt vor der Interpretation *vor* dessen Übergabe an den While-Befehl. Innerhalb des While-Befehls werden sie so wie nötig evaluiert.
If-Anweisung:
if { Bedingung } { FolgeVonTclKommandos }
Zuweisungen geschehen mit dem Kommando set - ohne ein Gleichheitszeichen. So ist auch hier kein Bruch in der extrem einfachen Syntax vorhanden:
set variable value
Weiter gibt es ein leistungsfähiges switch-Kommando, ein For- und ein Foreach-Kommando. Vor allem letzteres ist deutlich mächtiger als Iterationen in anderen Sprachen. Beispiel, um aus einer Liste von x/y-Koordinaten und einer weiteren aus z-Koordinaten eine Liste aus x/y/z-Koordinaten zu erstellen:
set xyzlist {} foreach {x y} $xylist z $zlist {lappend xyzlist [list $x $y $z]}
Es können also mehr als ein Element aus einer Liste, sowie Elemente aus mehreren Listen in einem Schleifendurchlauf verwendet werden.
Ein Kommando liefert einen Stringwert oder eine Liste als Resultat zurück.
glob aPattern
erzeugt eine Liste der Dateinamen im Arbeitsverzeichnis, deren Namen mit aPattern übereinstimmen. Pattern können ? (ein beliebiges Zeichen), * (0 oder mehr beliebige Zeichen) oder Klassen von Zeichen in eckigen Klammern enthalten. Dann aber sind letztere mit geschweiften Klammern vor zu früher Auswertung zu schützen:
glob {[abc]?-*.tcl}
liefert Datei- oder Verzeichnisnamen, die mit a, b oder c beginnen, danach aus einem beliebigen Zeichen und einem Bindestrich, danach einer beliebigen (auch leeren) Zeichenfolge und schließlich ".tcl" bestehen.
Arithmetische Ausdrücke werden durch das Kommando expr ausgeführt.
set res [expr 4 + 2 * 3] puts $res
ergibt 10. Die Dynamik der Datentypen erlaubt einfache Codierung wie diese:
proc Quersumme Zahl {expr [join [split $Zahl ""] +]}
* [split $Zahl ""] zerlegt die Zahl in Ziffern: 4711 -> 4 7 1 1 * [join ... +] fügt zwischen je zwei Ziffern ein "+"-Zeichen ein * [expr ...] berechnet schließlich den so entstandenen Ausdruck.
Datentypen
Tcl ist eine typlose Sprache. Jede Variable enthält Zeichenketten. Intern wird dann aber schon zwischen den Grund-Datentypen Ganzzahl, Fließkommazahl und Zeichenkette unterschieden. Die Verwendung einer nicht definierten Variable führt allerdings zu einem Fehler - im Gegensatz zur Programmierung mit dem Unix-Kommandozeileninterpreter oder awk. Konstrukte wie assoziative Arrays (Hashtabelle) und Listen werden in Tcl oft angewendet.
Das folgende Programmschnipsel deklariert implizit einen assoziativen Array und füllt ihn mit Werten.
set hauptstadt(Frankreich) Paris set hauptstadt(Italien) Rom set hauptstadt(Deutschland) Berlin set hauptstadt(Polen) Warschau set hauptstadt(Russland) Moskau set hauptstadt(Spanien) Madrid
Alternativ ist folgende Schreibweise möglich, und oft kompakter:
array set hauptstadt { Frankreich Paris Italien Rom Deutschland Berlin .. .. }
Ein bestimmter Wert kann wie folgt auf das Ausgabemedium geschrieben werden
puts $hauptstadt(Italien)
Eine Liste von allen Ländern zu denen Hauptstädte angegeben worden sind erzeugt der folgende Tcl-Befehl
array names hauptstadt
Der Tcl-Interpreter antwortet mit z.B.
Polen Spanien Russland Deutschland Italien Frankreich
Die Liste ist nicht sortiert. Die Liste wird sortiert ausgegeben mit:
lsort [array names hauptstadt]
Bearbeitung von Zeichenketten
Tcl kennt sehr leistungsfähige Kommandos zur Bearbeitung von (auch langen) Zeichenketten - mindestens ebenbürtig denen von Perl und Python, ebenso Dateibearbeitung, TCP/IP-Netzkommunikation und über Tk grafische Programmierung und ist in all diesem völlig plattformunabhängig. Tcl hat einen Mechanismus eingebaut, um mit Regulären Ausdrücken arbeiten zu können.
Einsatzbereiche
Tcl wird übrigens nicht nur auf der Kommandozeile, sondern auch als embedded language, als CGI-Sprache (wie sonst oft Perl) und als Modul im Apache-Webserver (wie sonst oft PHP) eingesetzt. Sie ist über eine einfache Schnittstelle zu C leicht erweiterbar.
Beispielprogramme
Fakultät
proc ! x {expr {$x<2? 1: $x*[! [incr x -1]]}}
Dies ist ein Beispiel für sehr kompakten, funktionalen Programmierstil. Es zeigt, daß beliebige Strings (hier "!") Namen von Funktionen sein können; daß innerhalb des expr-Kommandos auch der ternäre x?y:z-Operator wie aus C bekannt verfügbar ist; daß aber Tcl-Funktionen durchaus ganz anders als C-Programme aussehen können.
Digitaluhr
Hier ein kleines Beispielprogramm in Tcl/Tk, eine Digitaluhr in 6 Zeilen (Quelle: The Tcl'ers wiki - A simple A/D clock):
proc every {ms body} { eval $body after $ms [list every $ms $body] } pack [label .clock -textvar time] every 1000 {set ::time [clock format [clock sec] -format %H:%M:%S]}
In den ersten vier Zeilen wird ein Zeitgeber (Timer) angelegt, der ein Skript "body" regelmäßig alle "ms" Millisekunden ausführt (indem er sich selbst zum Wiederaufruf vormerken lässt). In der fünften Zeile wird ein Label in einem Fenster auf dem Bildschirm angelegt und mit einer Variablen "time" verbunden. In der sechsten Zeile wird der Timer "every" aufgerufen, um jede Sekunde die Variable "time" auf die aktuelle Uhrzeit im Format Stunde-Minute-Sekunde zu setzen. Fertig ist ein komplettes Programm mit GUI.
Arraydaten abfragen
Im Array tcl_platform liegen Angaben zur Plattform vor auf der der Tcl-Interpreter läuft. Das folgende Code-Stück gibt sie auf dem Standard-Ausgabemedium aus:
foreach i [array names tcl_platform] { puts [ concat $i= $tcl_platform($i) ] }
Eine hübschere Variante (alphabetisch sortiert, bündige Gleichheitszeichen) ist
parray tcl_platform
Minimaler Editor
Der folgende Code definiert einen kompletten minimalen Editor; er stammt von Richard Suchenwirth [1]; detaillierte Erklärungen unter [2]
# Hilfetext definieren set about "minEd - a minimal editor Richard Suchenwirth 2003 F1: help F2: load F3: save "
# GUI definieren, drei F-Tasten rufen Prozeduren auf pack [scrollbar .y -command ".t yview"] -side right -fill y pack [text .t -wrap word -yscrollc ".y set"] -side right -fill both -expand 1 bind . <F1> {tk_messageBox -message $about} bind . <F2> {loadText .t [tk_getOpenFile]} bind . <F3> {saveText .t [tk_getSaveFile]}
proc loadText {w fn} { if {$fn==""} return wm title . [file tail $fn] set fp [open $fn] $w delete 1.0 end $w insert end [read $fp] close $fp }
proc saveText {w fn} { if {$fn==""} return set fp [open $fn w] puts -nonewline $fp [$w get 1.0 "end - 1 c"] close $fp }
# Falls Editor mit Angabe einer Datei aufgerufen wurde, diese öffnen. if {$argc > 0} {loadText .t [lindex $argv 0]}
HTML-Seite herunterladen
Das http-Package enthält Befehle um mit dem http-Protokoll zu arbeiten. Die folgenden Codezeilen laden eine HTML-Seite herunter.
package require http puts [http::data [http::geturl http://mini.net/tcl/540]]
Erweiterungen
XOTcl ist eine objektorientierte Erweiterung. Sie unterstützt auch Metaklassen. Definitionen von Klassen und Methoden sind vollständig dynamisch änderbar.
Aufruf
Tcl ist in den meisten Unixinstallationen bereits voreinstalliert. Mit
tclsh
wird es aufgerufen. Wenn man auch das grafische Toolkit dabeihaben will, ist
wish
aufzurufen. (Seit Tcl 8.4 reicht die tclsh in allen Fällen aus, sofern interaktiv oder im Script
package require Tk
eingegeben wird.)
expect
enthält auch Tcl und ist speziell darauf ausgerichtet bestehende Kommandozeilen-Unix-Programme, die kein GUI haben mit einer Oberfläche zu versehen.
Für andere Betriebssysteme bestehen auch verschiedene Installationspakete. Interessant ist auch das TclKit, das für Windows aus einer einzigen weniger als 1MB grossen Datei besteht. Durch einfaches Kopieren dieser Datei wird Tcl mit Tk verfügbar gemacht. Eine Applikation, die gerne aus vielen Dateien bestehen kann, wird in einem Starkit (eine Datei) komprimiert und zusammengepackt, und ist plattformunabhängig lauffähig, sofern ein Tclkit vorhanden ist. Die Kombination aus einem Starkit und einem Tclkit in einem einzigen File wird "Starpack" genannt - sie erlaubt, eine Applikation in einer einzigen Datei (dann allerdings plattformspezifisch) auszuliefern.
Der Java-Wahlspruch write once - run anywhere wird hier Wahrheit; zumindest auf den Plattformen Unix (diverse), Windows (95..NT..XP..CE) und Mac.