打印Lua中当前作用域可访问的所有局部变量

时间:2010-05-14 13:46:37

标签: lua introspection

我知道如何使用以下代码打印“所有”全局变量

for k,v in pairs(_G) do
    print("Global key", k, "value", v)
end

所以我的问题是如何为当前正在执行的函数可以访问的所有变量执行此操作,这可以执行locals()为Python执行的操作。

5 个答案:

答案 0 :(得分:34)

以下是locals()函数的实现。它将从调用范围返回一个本地表:

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

请注意,在lua REPL中,每一行都是一个单独的块,具有不同的本地。此外,返回内部变量(名称以'('开头,如果你想删除它们):

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

感谢接受。你已经解开了拼图的最后一块! ; - )

Upvalues是来自外部作用域的局部变量,用于当前函数。他们既不在_G也不在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

示例(注意你必须使用它来显示它):

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

答案 1 :(得分:6)

使用debug.getlocal

答案 2 :(得分:2)

请参阅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

输出:

foobar  1
i       2

答案 3 :(得分:2)

以上法官Maygarden的循环版本的问题只是local i = 0。 它什么都不做,因为用'0'索引的第一个将始终返回nil。

记住Lua索引默认以'1'开头,而不是像C / C ++那样'0'。 您可以使用“0”作为具有您自己的类型的索引,但默认函数 期望默认值为'1'作为第一个索引。

只需将其更改为local i = 1,他的循环就可以正常使用。

答案 4 :(得分:0)

您可以使用getfenv来获取本地环境。

  

getfenv([f])返回当前值   功能使用的环境。 F   可以是Lua函数或数字   指定该堆栈的函数   级别:级别1是调用函数   getfenv。如果给定的功能不是   一个Lua函数,或者如果f是0,getfenv   返回全球环境。该   f的默认值为1。

编辑:抱歉,我错了。

我刚检查了Lua源代码。 debug.getlocal()是获取局部变量的唯一方法 Lua使用内部Proto结构,但不允许我们访问。{ (Proto持有本地属性加上父Proto引用。迭代函数的Proto,使用getfenv,
我们还迭代继承的属性,而不是我们想要的)

用户可以使用环境和set/getfenv函数或使用元表来定义 Proto