Skriptprogrammierung TclTk von Manuel Caroli Betreuer Thorsten Brunklaus
Skriptprogrammierung Tcl/Tk von Manuel Caroli Betreuer: Thorsten Brunklaus
Historisches • Scriptingsprachen gibt es seit den 60 er. Jahren • JCL, Unix Shells, Perl, Visual Basic, Python, Java. Script • Tcl: • Ende 80 er • John K. Ousterhout, Berkeley • aus der Not geboren 1. Es gab damals nur zu spezielle Kommandosprachen 2. Zeitverschwendung für Anpassung auf Tools
Einleitung: Tcl/Tk • Tcl: Skriptsprache • „Tool command language“ • tclsh (Shell für Tcl) • Tk: erweitert Tcl um Kommandos für GUI • „Toolkit“ • wish (Windowing Shell) • Interpreter bzw. Skriptdateien • „offizielle Aussprache“: Tickle
Das Kommando-Konzept Kommando Argument 1 Argument 2 Argument n • Ein Tcl-Skript besteht aus Kommandos • Kommandos werden Argumente übergeben • Argumente sind Strings • Anzahl der Argumente hängt vom Kommando ab
Das Kommando-Konzept (2) Kommando Argument 1 Argument 2 Argument n • Argumente: Trennung durch Leer / Tab • Kommandos: Trennung durch neue Zeile / ; • Argumente sind nicht weiter strukturiert
Beispiel: „fac“ proc {fac} {x} { if {$x <= 1} {return {1}} {expr {$x * [fac [expr {$x-1}]]}} } • Erzeugt ein neues Kommando, hier „fac“ • proc erwartet drei Argumente: proc {Kommandoname} {Argumentliste} {Block} proc { fac } { x } { if. . . }
Beispiel: „fac“ (2) if {$x <= 1} {return {1}} {expr {$x * [fac [expr {$x-1}]]}} • if erwartet auch drei Argumente: - if {Bedingung} {Block 1} {Block 2} - Bedingung true : Block 1 - Bedingung false: Block 2 if { $x <= 1 } { ret. . . } {. . . }
Quoting • Quoting geschieht durch {. . . } • String bleibt unverändert • Hier: das Kommando if erhält die Bedingung $x <= 1 zunächst als String • Beispiel: set a 10 set b $a => 10 set b {$a} => $a
Beispiel: „fac“ (3) expr {$x * [fac [expr {$x - 1}]]} • expr • Erwartet einen Ausdruck bestehend aus - Operanden - Operatoren - Klammern • Erwartet mindestens ein Argument • Argumente werden konkateniert • Klammern/Quoten ist also nicht notwendig
Substitution • 3 Varianten: $, , [. . . ] • set x 5 => $x wird durch 5 ersetzt • Sonderzeichen: $ wird durch $ ersetzt • [. . . ] wird ausgewertet und dann ersetzt • Beispiel: set a {expr 1+2} => expr 1+2 set a [expr 1+2] => 3
Beispiel: „fac“ (4) [fac [expr {$x - 1}]] • fac erwartet wie oben definiert eine Zahl • [expr {$x – 1}] wird zunächst ausgewertet • Dann kann fac ausgewertet werden
Quoting (2) • Weitere Art von Quoting: • Quoting durch ". . . " • Trennzeichen (Leerzeichen, neue Zeile) werden ignoriert • Substitution wie gewöhnlich • Beispiel: set a wort 1 wort 2 => Fehler set a "wort 1 wort 2" => wort 1 wort 2
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } fac 3
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } if "$x <= 1" {return 1} {expr. . . }
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } if "3 <= 1" {return 1} {expr. . . }
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "$x * [fac [expr {$x-1}]]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [fac [expr {$x-1}]]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [fac 2]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [if "$x<=1" {return 1} {expr. . . } ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [if "2<=1" {return 1} {expr. . . } ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "$x * [fac [expr {$x -1}] ]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * [fac [expr {$x -1}] ]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * [fac 1]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * [ if "$x<=1" {return 1} {expr. . . } ]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * [ if "1<=1" {return 1} {expr. . . } ]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * [return 1]" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * [expr "2 * 1" ]"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } expr "3 * 2"
Beispielauswertung „fac 3“ proc fac x { if "$x <= 1" {return 1} { expr "$x * [fac [expr {$x – 1}]]" } } 6
Scoping • Es gibt lokale und globale Variablen. • global x y macht die Variablen x und y innerhalb einer Prozedur verfügbar. • Das Kommando proc make. A {} { global A set A 1 } kann "A" erzeugen und global verfügbar machen
upvar • upvar macht Variablen außerhalb des Scopes verfügbar • make. A mit upvar: proc make. A {} { upvar #0 A a set a 1 } • #0 bedeutet global • n bedeutet um n "Ebenen" höher • default ist 1 • upvar ist also flexibler als global
Beispiel „make. Var“ proc make. Var {trunk init start end scope} { for {set i $start} {$i <= $end} {incr i} { upvar [expr $scope+1] $trunk$i a set a $init } } • Automatisierte Variablenerzeugung • Pass-by-name • make. Var a 0 0 10 0 erzeugt a 0, . . . , a 10
Weitere Kommandos • „Eingebaute“ Kommandos: • mathematische Operationen • Stringmanipulation • Listen • Kontrollstrukturen (while, foreach) • Fehlerbehandlung • Kommentare: # • „Externe“ Kommandos: • z. B. dir c: \
"quoting hell" if [1 <= 2] {1} {2} invalid command name "1" if {1 <= 2} {1} {2} invalid command name "1" • 1. Zeile: • Auswertung von [1 <= 2] • erwartet dass 1 ein Kommando ist • 2. Zeile: • Test erfolgreich zu „true“ ausgewertet • erwartet dass {1} ein Kommando ist
Tk – Toolkit • Erweitert Tcl um GUI • „Windowing Shell“: wish • Widgets • vorgefertigte grafische Elemente • Geometriemanager • Steuert die Anzeige von Widgets • Event-Management
Widgets • UI-Komponenten • Buttons • Menüs • Listboxes • etc. • Namen: hierarchisch • . main widget • . a. b : widget b ist „Kind“ von. a, ist „Kind“ von. • Widgetname ist zugleich Kommando
Geometriemanager • Packer Standard-Geometriemanager in Tk • Ordnet Widgets an • Passt die Größe von Widgets an • Kommando pack • Filling & Padding pack. ok. cancel. help -side left -padx 2 m -pady 1 m -fill y
Widgets - Beispiel button. top -text "Top button" pack. top button. bottom -text "Bottom button" pack. bottom • button erzeugt Buttons • pack macht Widgets (hier: Buttons) sichtbar • Neues Kommando. top: . top configure -relief sunken
Geometriemanager (2) • Placer alternativer Geometriemanager in Tk • Anordnung der Widgets manuell • Maße der Widgets manuell • Kommando place button. b -text "OK" place. b -x 10 -y 10 -width 100
Event Management: bind. b <Button-1> {. . . } bind. <Any-Key. Press> {puts "Taste %K"} bind all <Motion> {puts "Mausposition (%x, %y)"} • „Binden“ von events wie <Button-1> an entsprechende Reaktionen • Mehrere zeitgleich auftretende Events werden automatisch abgearbeitet
Canvas • Container-Widget für Grafische Primitive • Rechtecke, Kreise, Linien, etc. • Erzeugte Objekte ansteuerbar wie Widgets • Beispiel: pack [canvas. c]. c create oval 1 c 1 c 4 c 4 c -fill red
Gruppierung von Objekten • Jedes Obekt kann Marken (Tags) haben • Mehr als eine Marke erlaubt Hierarchische Gruppierung • Option -tag • Steuerung über diese Marken • Kommandos werden für alle Objekte mit dieser Marke ausgeführt • Beispiel: pack [canvas. c]. c create oval 1 c 1 c 2 c 2 c -tag Kreis. c create oval 2 c 2 c 3 c 3 c -tag Kreis. c itemconfigure Kreis -fill red
Fazit – Tcl • Vorteile • sehr flexibel • einfach • Nachteile • wird leicht unübersichtlich • "quoting hell" • schwierige Fehlersuche • langsam
Fazit – Tk • Vorteile • sehr einfache GUI-Erzeugung • ebenfalls flexibel • packer • Nachteile • langsam • Erst das Gespann "Tcl/Tk" war erfolgreich
Quellenangaben • John K. Ousterhout, Tcl and the Tk Toolkit, Addison-Wesley Professional Computing Series (1994) • John K. Ousterhout, Tcl: An Embeddable Command Language (USENIX Winter 1990) • John K. Ousterhout, An X 11 Toolkit Based on the Tcl Language (USENIX Winter 1991) • www. tcl. tk
- Slides: 45