第一版是为 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。保留所有权利。 |