2012-07-18 15 views
6

Sto riscontrando qualche problema nella comprensione dell'uso del livello superiore in TCL. Sto leggendo la programmazione Pratica di Brent Welch in TCL e Tk e c'è un esempio in uplevel che non riesco a capire. Eccolo:Impossibile capire il comando di livello superiore in TCL

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] 
} 

Qualcuno può spiegarmelo? La spiegazione nel libro non mi aiuta abbastanza :(

risposta

6

Il comando uplevel esegue un comando (o in effetti uno script) in un ambito diverso da quello della procedura corrente, in particolare in questo caso è uplevel 1 che significa “eseguito nel chiamante” (È inoltre possibile eseguire in ambito globale con uplevel #0, o in altri luoghi anche come il chiamante del chiamante con uplevel 2 ma questo è davvero raro.)

Spiegando il resto di quella linea:. il l'uso di list qui è come un modo di costruire un comando senza sostituzione, che consiste di quattro parole, foreach, il contenuto del Variabile args, il contenuto della variabile valueList e break (che in realtà non aveva bisogno di essere tra parentesi). Questo assegnerà un valore dalla parte anteriore di valueList a ciascuna variabile elencata in args, quindi si fermerà e lo farà nel contesto del chiamante.

Nel complesso, la procedura funziona come il lassign integrato in 8.5 (presupponendo un elenco di input non vuoto e un elenco di variabili), eccetto più lentamente a causa della complessità dello swap tra ambiti e cose del genere.

+1

In 8.6, siamo riusciti a trovare un utilizzo per 'uplevel # 1' con coroutine. Questo è stato considerato il primo uso pratico per questa particolare forma, anche se è legale da decenni. –

+0

La sintassi * # * è descritta in questo modo: "Se * livello * è composto da # seguito da un numero, il numero fornisce un numero di livello assoluto." http://www.tcl.tk/man/tcl8.5/TclCmd/uplevel.htm –

+0

@DonalFellows Non 'tailcall' lo stack' coroutine' in cima. –

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" 

qui il metodo più all'interno di una è a livello 0 e b del livello, c di livello 2 e programma principale sarà nel livello 3 così in proc una se cambio il valore di livello allora posso cambiare il valore della variabile x di qualsiasi proc sia a, b, c o main proc dal metodo "a" stesso. prova a cambiare livello a 3,2,1,0 e vedi la magia putput.

Problemi correlati