关于lua:为什么debug.getinfo(1)的’name’为nil

Why is 'name' nil for debug.getinfo(1)

我正在尝试建立一个lua测试框架,让您知道出现问题的函数,但是当我从loadstring切换到_G时,(我进行了切换,以便测试工具可以看到函数调用的结果) 函数以'nil'作为函数名称开始

为什么在以下代码中_G无法检测到当前函数的名称? 另外,当使用_G时,如何从加载字符串中获得返回结果(即从blah调用中返回" false")或设置函数名称(即,告诉lua解释器函数名称应为什么)?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function run_test(one, two)
    if one ~= two then
        print(debug.getinfo(2).name..' Failed')
    end
end

function blah()
    run_test(false, true)
    return false
end

local fname = 'blah'
local status, result = pcall(_G[fname])  -- Outputs 'nil'; result is 'false'
local status, result = pcall(loadstring(fname..'()'))  -- Outputs 'blah', result is 'nil'

我需要的主要是一种使用函数名称字符串调用函数的方法,能够看到调用内部的函数名称(用于测试失败以指向失败的函数,如fname ='blah' 上面的代码)并能够获取返回值

1
2
3
4
5
6
local fname = 'blah'
status, result = pcall(??Call fname somehow??)
assert(status)
assert(not result)

--stdout should be"blah Failed"


这是Lua用于提供函数名称的启发式方法的限制。

在Lua中,所有功能都是匿名的。给定的函数可以是多个变量的值:全局,局部和表字段。 Lua调试系统会通过查看正在执行的字节码来尝试根据值的来源找到一个合理的名称。

考虑更简单的例子

1
2
blah()
pcall(blah)

在第一个调用中,调试系统会看到正在调用的函数来自全局blah,而debug.getinfo(1).name给出了预期的结果blah

在第二次调用中,调试系统看到正在调用的函数来自pcall的第一个参数,但不再看该参数的来源,而debug.getinfo(1).name给出了nil

当您调用_G[name]()时,也会发生同样的事情。调试系统仅看到一个表的字段,并且该字段的名称相距太远。

尝试将print(debug.traceback())添加为blah的第一行,以查看对该解释的另一种理解。