第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但存在一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目


23.1 – 自省工具

debug 库中的主要自省函数是 debug.getinfo 函数。它的第一个参数可以是函数或堆栈级别。当您为某个函数 foo 调用 debug.getinfo(foo) 时,您会得到一个包含有关该函数的一些数据的数据表。数据表可能具有以下字段

foo 是 C 函数时,Lua 没有太多关于它的数据。对于此类函数,只有 whatnamenamewhat 字段是相关的。

当您为某个数字 n 调用 debug.getinfo(n) 时,您会得到该堆栈级别上活动函数的数据。例如,如果 n 为 1,您会得到执行调用的函数的数据。(当 n 为 0 时,您会得到关于 getinfo 本身(一个 C 函数)的数据。)如果 n 大于堆栈中活动函数的数量,debug.getinfo 会返回 nil。当您查询活动函数(使用数字调用 debug.getinfo)时,结果数据表有一个额外的字段 currentline,其中包含函数在该时刻所在的行。此外,func 具有该级别上活动的函数。

name 字段很棘手。记住,因为函数在 Lua 中是一等值,所以函数可能没有名称,或者可能有多个名称。Lua 尝试通过查找具有该值的一个全局变量,或者查看调用函数的代码以查看它是如何调用的,来查找函数的名称。第二个选项仅在我们使用数字调用 getinfo 时才起作用,也就是说,我们获取有关特定调用的信息。

getinfo 函数效率不高。Lua 以不损害程序执行的形式保留调试信息;高效检索在这里是次要目标。为了获得更好的性能,getinfo 有一个可选的第二个参数,用于选择要获取的信息。使用此参数,它不会浪费时间收集用户不需要的数据。此参数的格式为字符串,其中每个字母根据下表选择一组数据

`n´选择字段 namenamewhat
`f´选择字段 func
`S´选择字段 sourceshort_srcwhatlinedefined
`l´选择字段 currentline
`u´选择字段 nup

以下函数说明了 debug.getinfo 的用法。它打印活动堆栈的原始回溯

    function traceback ()
      local level = 1
      while true do
        local info = debug.getinfo(level, "Sl")
        if not info then break end
        if info.what == "C" then   -- is a C function?
          print(level, "C function")
        else   -- a Lua function
          print(string.format("[%s]:%d",
                              info.short_src, info.currentline))
        end
        level = level + 1
      end
    end
改进此函数并不困难,包括 getinfo 的更多数据。实际上,调试库提供了这样一个改进版本,debug.traceback。与我们的版本不同,debug.traceback 不会打印其结果;相反,它返回一个字符串。