Kurz: Mit coroutine unterbrechen und fortsetzen Prozeduren ihre Arbeit – ideal für Generatoren:
Teil des Kurses Tcl
Coroutinen
Mit coroutine unterbrechen und fortsetzen Prozeduren ihre Arbeit – ideal für Generatoren:
proc generator {} {
yield
for {set i 1} {$i <= 5} {incr i} { yield [expr {$i * $i}] }
return -code break
}
coroutine quadrate generator
while 1 {
set wert [quadrate]
puts -nonewline "$wert "
if {[catch {quadrate} _]} break
}
puts ""
proc fib_gen {} {
yield
set a 0; set b 1
while 1 {
yield $a
lassign [list $b [expr {$a + $b}]] a b
}
}
coroutine fib fib_gen
for {set i 0} {$i < 10} {incr i} { puts -nonewline "[fib] " }
puts ""
rename fib {}Ausgabe:
1 9 25
0 1 1 2 3 5 8 13 21 34Traces
Mit trace reagiert man auf Zugriffe, Änderungen oder Prozeduraufrufe:
proc beobachte {name index op} {
upvar 1 $name var
puts " $name geändert: $var"
}
set wert 0
trace add variable wert write beobachte
set wert 5
incr wert
set wert 42
trace remove variable wert write beobachte
set wert 99
puts $wert
proc rechne {a b} { return [expr {$a * $b}] }
trace add execution rechne enter {apply {{cmd op} { puts " -> ruft $cmd" }}}
puts [rechne 6 7]Ausgabe:
wert geändert: 5
wert geändert: 6
wert geändert: 42
99
-> ruft rechne 6 7
42Befehle umbenennen und Introspektion
rename puts alt_puts
proc puts {text} {
alt_puts [string toupper $text]
}
puts "hallo welt"
rename puts {}
rename alt_puts puts
puts "wieder normal"
proc beispiel {a {b 2} args} {}
puts [info args beispiel]
puts [info default beispiel b wert]
puts $wert
puts [info exists ::tcl_version]
puts [info level]
proc tief {} { return [info level] }
puts [tief]
puts [expr {[lsearch [info commands] while] >= 0}]Ausgabe:
HALLO WELT
wieder normal
a b args
1
2
1
0
1
1Sichere Interpreter
Unvertrauenswürdigen Code führt man in einem Safe Interpreter aus:
set sicher [interp create -safe]
puts [$sicher eval {expr {6 * 7}}]
puts [$sicher eval {string toupper "ok"}]
if {[catch {$sicher eval {exec ls}} fehler]} { puts "blockiert: $fehler" }
if {[catch {$sicher eval {open /etc/passwd}} fehler]} { puts "blockiert: $fehler" }
$sicher alias hallo apply {{x} { return "Hallo, $x!" }}
puts [$sicher eval {hallo Mia}]
interp delete $sicherAusgabe:
42
OK
blockiert: invalid command name "exec"
blockiert: invalid command name "open"
Hallo, Mia!Merke
coroutineundyieldbauen Generatoren und kooperative Abläufetraceüberwacht Variablen und Befehle- Befehle lassen sich mit
renameersetzen;infoliefert Introspektion - Safe Interpreter führen fremden Code mit eingeschränkten Rechten aus
Übungsaufgabe
Baue einen Generator, der nacheinander Primzahlen liefert.
Quiz zur Selbstkontrolle
Wofür ist yield in Tcl?
- Unterbricht eine Coroutine und liefert einen Wert (richtig)
- Beendet das Programm
- Erzeugt einen Thread
- Definiert eine Variable
Was bewirkt trace add variable?
- Ruft eine Prozedur bei Zugriff/Änderung der Variable auf (richtig)
- Löscht die Variable
- Gibt Speicher frei
- Debuggt Fehler
Wofür dient interp create -safe?
- Einen eingeschränkten Interpreter für fremden Code (richtig)
- Einen schnellen Interpreter
- Einen Debugger
- Eine Datenbank
Weiter im Kurs
Zurück: Praxisprojekte
Weiter: Referenz und Spickzettel
Alle Kapitel: Tcl im Überblick