2010-05-14 9 views

Antwort

30

Hier eine Implementierung einer locals() Funktion ist. Es wird eine Tabelle von Einheimischen aus dem rufenden Umfang zurück:

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 

Beachten Sie, dass in der lua REPL, wobei jede Zeile eine separate Brocken mit separaten Einheimischen ist. Außerdem werden interne Variablen zurückgegeben (Namen beginnen mit ‚(‘ wenn man sie entfernen möchten.):

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

Vielen Dank für das akzeptieren Sie haben das letzte Stück des Puzzles entriegelt ;-)

!

Upvalues ​​sind lokale Variablen aus äußeren Bereichen, die in der aktuellen Funktion verwendet werden.Sie sind weder in _G noch in 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 

Beispiel (beachten Sie haben eine verwenden, um es zu zeigen):

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

Funktioniert perfekt! Vielen Dank! –

+0

Warum speichert "Paare" in '(* temporäre)'? –

+0

glücklich, es ist eine Lua Implementierung Sache – u0b34a0f6ae

0

Sie können getfenv verwenden, um eine lokale Umgebung zu erhalten.

getfenv ([f]) durch die Funktion der aktuellen Umgebung im Einsatz zurück. f kann eine Lua-Funktion oder eine Nummer sein, die die Funktion auf diesem Stapel angibt Ebene: Ebene 1 ist die Funktion Aufruf getfenv. Wenn die angegebene Funktion nicht eine Lua-Funktion ist oder wenn f 0 ist, gibt getfenv die globale Umgebung zurück. Die Standard für f 1.

Edit: sorry, ich war falsch.

Ich habe gerade Lua Quellcode überprüft. debug.getlocal() ist die einzige Möglichkeit, die lokalen Variablen zu erhalten.
Lua verwendet eine interne Proto Struktur und gibt uns keinen Zugriff darauf.
(hält Proto lokalen Eigenschaften sowie ein Elternteil Proto Referenz. Proto Iterieren Funktion, durch getfenv Verwendung
wir auch vererbte Eigenschaften laufen, nicht das, was wir wollten) ihre Proto s

Benutzer können entweder mit Umgebungen definieren und die set/getfenv Funktionen oder mithilfe von Metatabellen.

+0

Ihre Lösung hat nicht funktioniert. Das Folgende druckt 'foobar' nicht: local foobar = 1; für k, v in Paaren (getfenv()) do print (k, v) end Fehle ich etwas? –

+0

Ich glaube, 'getfenv' zeigt nur Globals mit dem gegebenen Umfang/Umgebung. –

+0

@Judge, ja, aber wir können Funktion env durch einige andere ersetzen. Wie ich entdeckt habe, durchlaufen wir, wenn wir über ein env iterieren, auch die vererbte Kette von internen Prototypen. Wir können nicht wirklich lokale Deklarationen erhalten, wenn wir nicht das eingebaute 'debug.getlocal' benutzen. –

6

Verwenden Sie debug.getlocal.

+3

Es ist zu kurz, um nützlich zu sein für jemanden, der mit der Frage, die ich gestellt habe, ins Internet kommt. Danke trotzdem! –

2

Siehe 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 

Ausgang:

foobar 1 
i  2 
+0

Haben Sie den Code ausgeführt, den Sie eingefügt haben? Ich benutze es mit Lua 5.1.4 unter Ubuntu und es wird überhaupt nichts gedruckt. Ich habe den Code in einer Datei gespeichert und in der Konsole mit 'lua test.lua' ausgeführt. Fehle ich etwas? –

+0

Ja, ich habe es auf Ubuntu 10.04 mit der gleichen Version von Lua ausgeführt. –

+0

Haben Sie es in eine Datei eingefügt oder in einen Funktionsaufruf eingeschlossen? –

2

Das Problem mit Richter Maygarden-Schleife Version oben ist einfach local i = 0. Es tut nichts, weil das erste, das mit '0' indiziert wird, immer nil zurückgibt.

Denken Sie daran, Lua-Indizes standardmäßig mit '1' beginnen, nicht '0' wie C/C++. Sie können '0' für einen Index mit Ihren eigenen Kursarten verwenden, aber die Standardfunktionen erwarten den Standardwert '1' als ersten Index.

Ändern Sie einfach zu local i = 1 und seine Schleife wird gut funktionieren.