2012-07-18 9 views
6

Ich habe einige Probleme, die Verwendung von uplevel in TCL zu verstehen. Ich lese Brent Welchs Praktische Programmierung in TCL und Tk und es gibt ein Beispiel in der oberen Ebene, das ich nicht verstehen kann. Hier ist es:Kann Uplevel-Befehl in TCL nicht verstehen

proc lassign {valueList args} { 
    if {[llength $args] == 0} { 
    error "wrong # args:lassign list varname ?varname...?" 
    } 
    if {[llength $valueList] == 0} { 
    #Ensure one trip through the foreach loop 
    set valueList [List {}] 
    } 
    uplevel 1 [list foreach $args $valueList {break}] 
    return [lrange $valueList [llength $args] end] 
} 

Kann mir bitte jemand es erklären? Die Erklärung in dem Buch hilft mir nicht genug :(

Antwort

6

Der Befehl uplevel führt einen Befehl (oder tatsächlich ein Skript) in einem anderen Bereich als der der aktuellen Prozedur.In diesem Fall ist es uplevel 1, was bedeutet „execute in Anrufern“ (Sie auch im globalen Bereich mit uplevel #0 oder an anderen Orten zu wie der Anrufer Anrufer mit uplevel 2 ausführen können, aber das ist wirklich selten.)

den Rest dieser Zeile erklären. die Verwendung der list hier ist als eine Möglichkeit, einen ersatzfreien Befehl zu konstruieren, der aus vier Wörtern besteht, foreach, der Inhalt der args Variable, der Inhalt von valueList Variable und break (die nicht wirklich in Klammern sein musste). Damit wird jeder Variablen, die in args aufgeführt ist, ein Wert von valueList vorangestellt und dann gestoppt, und zwar im Kontext des Aufrufers.

Insgesamt funktioniert das Verfahren genau wie das eingebaute lassign in 8.5 (Annahme einer nicht leeren Eingabeliste und Variablenliste), außer langsamer wegen der Komplexität des Swapping zwischen Bereichen und solchen Dingen.

+1

In 8.6 haben wir gefunden, eine Verwendung für 'uplevel # 1' mit Koroutinen zu finden. Dies wurde als der erste praktische Gebrauch _ever_ für diese bestimmte Form betrachtet, obwohl es seit Jahrzehnten legal ist. –

+0

Die * # * Syntax wird folgendermaßen beschrieben: "Wenn * level * aus # besteht, gefolgt von einer Zahl, dann gibt die Zahl eine absolute Nummer." http://www.tcl.tk/man/tcl8.5/TclCmd/uplevel.htm –

+0

@DonalFellows Nicht "tailcall" den oberen "Coroutine" Stapel. –

3
proc a {} { 
    set x a 
    uplevel 3 {set x Hi} 
    puts "x in a = $x" 
} 
proc b {} { 
    set x b 
    a 
    puts "x in b = $x" 
} 
proc c {} { 
    set x c 
    b 
    puts "x in c = $x" 
} 
set x main 
c 
puts "x in main == $x" 

hier die innerhalb Methode A in Ebene 0 und B in Ebene sein wird, c in Stufe 2 und Hauptprogramm in Ebene sein wird, 3 so in proc a, wenn i den Wert Stufe ändern kann ich ändern der Wert der Variablen x eines beliebigen Prozesses, sei es a, b, c oder main proc aus der Methode "a" selbst. versuchen, das Niveau auf 3,2,1,0 zu ändern und den magischen Putput zu sehen.