2012-07-18 5 views
6

Tengo algunos problemas para entender el uso del nivel de nivel superior en TCL. Estoy leyendo la programación práctica de Brent Welch en TCL y Tk y hay un ejemplo en el nivel superior que no puedo entender. Aquí está:No se puede entender el comando de nivel de nivel en 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] 
} 

¿Alguien me puede explicar por favor? La explicación en el libro no me ayuda lo suficiente :(

Respuesta

6

El comando uplevel ejecuta un comando (o de hecho un script) en otro ámbito que el del procedimiento actual. En particular, en este caso es uplevel 1 lo que significa “ejecutar en el que llama” (Usted también puede ejecutar en el ámbito global con uplevel #0, o en otros lugares también como la persona que llama de la persona que llama con uplevel 2 pero eso es realmente rara.)

al explicar el resto de la línea:. el El uso del list aquí es como una forma de construir un comando libre de sustitución, que consiste en cuatro palabras, foreach, el contenido del args variable, el contenido de la variable valueList y break (que en realidad no tenía que estar entre llaves). Eso asignará un valor desde el frente de valueList a cada variable enumerada en args, y luego se detendrá, y lo hará en el contexto de la persona que llama.

En general, el procedimiento funciona igual que el lassign incorporado en 8.5 (suponiendo una lista de entradas y listas de variables no vacías), excepto más lento debido a la complejidad del intercambio entre ámbitos y cosas por el estilo.

+1

En 8.6, logramos encontrar un uso para 'uplevel # 1' con corutinas. Este fue considerado como el primer uso práctico _ever_ para esa forma particular, a pesar de que ha sido legal durante décadas. –

+0

La sintaxis * # * se describe así: "Si * nivel * consiste en # seguido de un número, entonces el número da un número de nivel absoluto". http://www.tcl.tk/man/tcl8.5/TclCmd/uplevel.htm –

+0

@DonalFellows No 'tailcall' la pila superior de 'coroutine'. –

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" 

aquí el método más dentro de una habrá en nivel 0 y b de nivel, c en el nivel 2 y el programa principal estará en nivel 3 por lo que en proc un si cambio el valor de nivel después puedo cambiar el valor de la variable x de cualquier proceso sea a, b, c o proc principal del método "a" mismo. intente cambiar el nivel a 3,2,1,0 y vea el putput mágico.

Cuestiones relacionadas