第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但存在一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目。
![]() |
用 Lua 编程 | ![]() |
| 第三部分。标准库 第 23 章。调试库 |
debug 库中的主要自省函数是 debug.getinfo 函数。它的第一个参数可以是函数或堆栈级别。当您为某个函数 foo 调用 debug.getinfo(foo) 时,您会得到一个包含有关该函数的一些数据的数据表。数据表可能具有以下字段
source --- 定义函数的位置。如果函数是在字符串中定义的(通过 loadstring),source 就是该字符串。如果函数是在文件中定义的,source 就是文件名称,前面加上 `@´。
short_src --- source 的简短版本(最多 60 个字符),适用于错误消息。
linedefined --- 定义函数的源代码行。
what --- 此函数是什么。如果 foo 是常规 Lua 函数,选项为 "Lua";如果它是 C 函数,选项为 "C";如果它是 Lua 块的主要部分,选项为 "main"。
name --- 函数的合理名称。
namewhat --- 上一个字段的含义。此字段可以是 "global"、"local"、"method"、"field" 或 ""(空字符串)。空字符串表示 Lua 没有找到函数的名称。
nups --- 该函数的上值数量。
func --- 函数本身;请参阅后面内容。
当 foo 是 C 函数时,Lua 没有太多关于它的数据。对于此类函数,只有 what、name 和 namewhat 字段是相关的。
当您为某个数字 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´ | 选择字段 name 和 namewhat |
`f´ | 选择字段 func |
`S´ | 选择字段 source、short_src、what 和 linedefined |
`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 不会打印其结果;相反,它返回一个字符串。
| 版权所有 © 2003-2004 Roberto Ierusalimschy。保留所有权利。 | ![]() |