450 likes | 553 Views
Skriptprogrammierung Tcl/Tk von Manuel Caroli Betreuer: Thorsten Brunklaus. Historisches. Scriptingsprachen gibt es seit den 60er-Jahren JCL, Unix Shells, Perl, Visual Basic, Python, JavaScript Tcl: Ende 80er John K. Ousterhout, Berkeley aus der Not geboren
E N D
SkriptprogrammierungTcl/TkvonManuel Caroli Betreuer: Thorsten Brunklaus
Historisches • Scriptingsprachen gibt es seit den 60er-Jahren • JCL, Unix Shells, Perl, Visual Basic, Python, JavaScript • Tcl: • Ende 80er • John K. Ousterhout, Berkeley • aus der Not geboren • Es gab damals nur zu spezielle Kommandosprachen • 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 • Ein Tcl-Skript besteht aus Kommandos • Kommandos werden Argumente übergeben • Argumente sind Strings • Anzahl der Argumente hängt vom Kommando ab Kommando Argument 1 Argument 2 Argument n
Das Kommando-Konzept (2) • Argumente: Trennung durch Leer / Tab • Kommandos: Trennung durch neue Zeile / ; • Argumente sind nicht weiter strukturiert Kommando Argument 1 Argument 2 Argument n
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} {Block1} {Block2} • Bedingung true : Block1 • Bedingung false: Block2 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 wort1 wort2 => Fehler set a "wort1 wort2" => wort1 wort2
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 makeA {} { global A set A 1 } kann "A" erzeugen und global verfügbar machen
upvar • upvar macht Variablen außerhalb des Scopes verfügbar • makeA mit upvar: proc makeA {} { 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 „makeVar“ proc makeVar {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 • makeVar a 0 0 10 0 erzeugt a0, ..., a10
Weitere Kommandos • „Eingebaute“ Kommandos: • mathematische Operationen • Stringmanipulation • Listen • Kontrollstrukturen (while, for, 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 2m -pady 1m -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 bind .b <Button-1> {...} bind . <Any-KeyPress> {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 1c 1c 4c 4c -fill red
Gruppierung von Objekten • JedesObektkann 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 1c 1c 2c 2c -tag Kreis .c create oval 2c 2c 3c 3c -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 X11 Toolkit Based on the Tcl Language (USENIX Winter 1991) • www.tcl.tk