问题
I'm trying to put together a lua testing framework that lets you know the function that had the problem, but when I switched from loadstring to _G
, (I switched so my test harness could see the results of the function call) my functions started using 'nil' for the function name
Why can _G
not detect the name of the current function in the following code? Also, how can I get the return results from loadstring (ie the 'false' from the blah call) or set the function name when using _G
(ie. Tell the lua interpreter what the function name should be)?
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'
The main thing I need is a way to call a function using a string of the function name, be able to see the function name inside the call (for test failures to point to the function that failed, like fname = 'blah' in the code above) and be able to get the return value
local fname = 'blah'
status, result = pcall(??Call fname somehow??)
assert(status)
assert(not result)
--stdout should be "blah Failed"
回答1:
This is a limitation of the heuristics used by Lua to provide names for functions.
In Lua, all functions are anonymous. A given function can be the value of several variables: global, local, and table fields. The Lua debug system tries to find a reasonable name for a value based on where it came from by looking into the bytecode being executed.
Consider the simpler example
blah()
pcall(blah)
In the first call, the debug system sees that the function being called comes from the global blah
and debug.getinfo(1).name
gives the expected result, blah
.
In the second call, the debug system sees that the function being called comes from the first argument to pcall
but it does not look further to see where that argument came from, and debug.getinfo(1).name
gives nil
.
The same thing happens when you call _G[name]()
. All the debug system sees is a field of a table and the name of the field is too far off.
Try adding print(debug.traceback())
as the first line of blah
to see another take on this explanation.
来源:https://stackoverflow.com/questions/18499086/why-is-name-nil-for-debug-getinfo1