如何在错误消息中显示正确的函数名称?

假设我间接调用一些函数,通过一个变量来调用。比如:

obj = {

  on_init = function()
    print "hello."
  end,

  on_destroy = function()
    print "bye."
  end,

  on_do_something = function()
    print "doing something."
    error("Hi de hi, hi de ho!")
  end,

}

local event = "do_something"
local func = obj["on_" .. event]
func()

一切运转良好。

然而,问题在于当调用的函数引发异常(如上面的代码)时,错误消息不够清楚。它因此为:

lua: test.lua:13: Hi de hi, hi de ho!
stack traceback:
    [C]: in function 'error'
    test.lua:13: in function 'func'
    test.lua:20: in main chunk

它说“在函数 'func' 中”。我希望它能说“在函数 'on_do_something' 中”。

我想象这种情况非常常见。有没有解决办法?

我尝试这样调用函数:

obj["on_" .. event]()

但是错误消息会说“在函数 '?' 中”,这也不是很有用。

(我在 Lua 5.1、5.2 和 LuaJIT 上尝试了这个代码,没有显著的差异。)

点赞
用户107090
用户107090

这是 Lua 用于为函数提供名字的启发式算法的限制。

在 Lua 中,所有函数都是匿名的。同一个函数可以是全局变量、局部变量和表格字段的值。Lua 的调试系统(用于错误处理)尝试根据执行的字节码来查找一个合理的名称,以便为一个值命名。

参见 为什么 debug.getinfo(1) 的 'name' 是 nil

2013-11-27 11:51:14
用户869951
用户869951

你有一些选项。调试模块会尝试生成有用的信息。例如,如果这是你自己的代码,你可能能够获取定义它的文件名和行号。请参见http://www.lua.org/pil/23.1.html以获取通过调试模块获取信息的列表。或者,你可能能够在模块中定义函数,然后将它们添加到表中:

-- 模块 something
function a()
    ...
end

tt = {
    fn1 = a,
    ...
}

根据你在哪里捕获错误(通过调试挂钩安装的错误处理程序?),你可以检查文件名是否为定义函数表的模块,如果是,则根据你的表结构使用调试模块打印适当的信息;如果不是,则只需打印默认的跟踪信息等。

2013-11-27 15:08:13