Reputation: 10387
I know how to print "all" global variables using the following code
for k,v in pairs(_G) do
print("Global key", k, "value", v)
end
So my question is how to do that for all variables that are accessible from the currently executing function, something that can do what locals()
does for Python.
Upvotes: 32
Views: 38257
Reputation: 736
The problem with Judge Maygarden's loop version above is simply local i = 0
.
It does nothing because the first indexed with '0' will always return nil.
Remember Lua indexes by default start with '1', not '0' like C/C++. You can use '0' for an index with your own types of course, but the default functions are expecting the default of '1' as the first index.
Just change it to local i = 1
and his loop will work fine.
Upvotes: 4
Reputation: 49843
Here is an implementation of a locals()
function. It will return a table of locals from the calling scope:
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
Notice that in the lua REPL, each line is a separate chunk with separate locals. Also, internal variables are returned (names start with '(' if you want to remove them):
> local a = 2; for x, v in pairs(locals()) do print(x, v) end
a 2
(*temporary) function: 0x10359b38
Thanks for the accept. You have unlocked the last piece of the puzzle! ;-)
Upvalues are local variables from outer scopes, that are used in the current function. They are neither in _G
nor 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
Example (notice you have to use a for it to show up):
> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f()
a 2
Upvotes: 42
Reputation: 43158
You can use getfenv to get a local environment.
getfenv ([f]) Returns the current environment in use by the function. f can be a Lua function or a number that specifies the function at that stack level: Level 1 is the function calling getfenv. If the given function is not a Lua function, or if f is 0, getfenv returns the global environment. The default for f is 1.
Edit: sorry, I was wrong.
I just checked Lua source code. debug.getlocal()
is the only way to get the local variables.
Lua uses an internal Proto structure and doesn't give us access to that.
(Proto holds local properties plus a parent Proto reference. Iterating function's Proto, by using getfenv,
we also iterate inherited properties, not what we wanted)
Users can define their Proto s either with environments and the set/getfenv
functions or by using metatables.
Upvotes: 0
Reputation: 27613
See 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
Output:
foobar 1
i 2
Upvotes: 3