2010-05-14 11 views

Respuesta

30

Aquí es una implementación de una función locals(). Se devolverá una tabla de los locales del ámbito de llamar:

function locals() 
    local variables = {} 
    local idx = 1 
    while true do 
    local ln, lv = debug.getlocal(2, idx) 
    if ln ~= nil then 
     variables[ln] = lv 
    else 
     break 
    end 
    idx = 1 + idx 
    end 
    return variables 
end 

en cuenta que en el REPL lua, cada línea es una parte separada con los locales separados. Además, las variables internas se devuelven (nombres comienzan con '(' si quieres eliminarlos):.

> local a = 2; for x, v in pairs(locals()) do print(x, v) end 
a 2 
(*temporary) function: 0x10359b38 

Gracias por el aceptar que haya desbloqueado la última pieza del rompecabezas ;-)

!

Los valores ascendentes son variables locales de los ámbitos externos que se utilizan en la función actual.No son ni en _G ni en locals()

function upvalues() 
    local variables = {} 
    local idx = 1 
    local func = debug.getinfo(2, "f").func 
    while true do 
    local ln, lv = debug.getupvalue(func, idx) 
    if ln ~= nil then 
     variables[ln] = lv 
    else 
     break 
    end 
    idx = 1 + idx 
    end 
    return variables 
end 

Ejemplo (nótese que hay que utilizar una para que aparezca):

> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f() 
a 2 
+0

¡Funciona perfectamente! ¡Muchas gracias! –

+0

¿Por qué almacena 'pares' en' (* temporal) '? –

+0

feliz, es una cosa de implementación Lua – u0b34a0f6ae

0

Puede usar getfenv para obtener un entorno local.

getfenv ([f]) Devuelve el actual entorno en uso por la función. f puede ser una función Lua o un número que especifica la función en ese nivel de pila : El nivel 1 es la función que llama a getfenv. Si la función dada no es una función Lua, o si f es 0, getfenv devuelve el entorno global. El valor predeterminado para f es 1.

Editar: Lo siento, estaba equivocado.

Acabo de comprobar el código fuente de Lua. debug.getlocal() es la única forma de obtener las variables locales.
Lua usa una estructura interna Proto y no nos da acceso a eso.
(Proto tiene propiedades locales además de uno de los padres de Proto de la función Proto referencia. Iteración, mediante el uso de getfenv,
también iteramos propiedades heredadas, no es lo que queríamos)

usuarios pueden definir sus Proto s ya sea con entornos y las funciones set/getfenv o usando metatables.

+0

Su solución no funcionó. Lo siguiente no imprime 'foobar': local foobar = 1; para k, v en pares (getfenv()) imprimir (k, v) finalizar ¿Me falta algo? –

+0

Creo que 'getfenv' solo mostrará los globales dentro del alcance/entorno. –

+0

@Judge, sí, pero podemos reemplazar el env de la función por otro. Como descubrí, cuando iteramos sobre un env también iteramos sobre la cadena heredada de prototipos internos. Realmente no podemos obtener declaraciones locales a menos que usemos el 'debug.getlocal' incorporado. –

6

Use debug.getlocal.

+3

Es demasiado corto para ser útil para alguien que accede a la web con la pregunta que hice. ¡Pero gracias de cualquier manera! –

2

Ver debug.getlocal:

local foobar = 1 

local i = 0 
repeat 
    local k, v = debug.getlocal(1, i) 
    if k then 
     print(k, v) 
     i = i + 1 
    end 
until nil == k 

Salida:

foobar 1 
i  2 
+0

¿Ejecutaste el código que pegaste? Lo estoy ejecutando usando Lua 5.1.4 en Ubuntu y no imprime nada en absoluto. Guardé el código en un archivo y lo ejecuté en la consola con 'lua test.lua'. ¿Me estoy perdiendo de algo? –

+0

Sí, lo ejecuté en Ubuntu 10.04 con la misma versión de Lua. –

+0

¿Lo colocó en un archivo como está o lo envuelve en una llamada a función? –

2

El problema con la versión de bucle del juez Maygarden anterior es simplemente local i = 0. No hace nada porque el primero indexado con '0' siempre devolverá nil.

Recuerde que los índices Lua por defecto comienzan con '1', no '0' como C/C++. Puede usar '0' para un índice con sus propios tipos de curso, pero las funciones predeterminadas esperan el valor predeterminado de '1' como primer índice.

Simplemente cámbialo a local i = 1 y su bucle funcionará bien.

Cuestiones relacionadas