debug实现反射功能:获取函数信息、函数局部变量、函数使用的外部局部变量等
getinfo(thread, f, what):获取函数的表信息
Returns a table with information about a function. You can give the
function directly or you can give a number as the value of f, which
means the function running at level f of the call stack of the given
thread: level 0 is the current function (getinfo itself); level 1 is
the function that called getinfo (except for tail calls, which do not
count in the stack); and so on. If f is a number greater than the
number of active functions, then getinfo returns fail.
* 以表的形式返回函数的信息
* f可以直接指定为函数、函数的栈
* f=0:getinfo函数
* f=1:调用getinfo的函数fun
* f=2:调用fun的函数
* 如果没有函数信息,返回nil
* 说明:f从0往上表示调用该函数的函数,不能向下(该函数调用的函数)
The returned table can contain all the fields returned by lua_getinfo,
with the string what describing which fields to fill in. The default
for what is to get all information available, except the table of
valid lines. If present, the option 'f' adds a field named func with
the function itself. If present, the option 'L' adds a field named
activelines with the table of valid lines.
* 默认会返回所有函数的信息
* what=f:表中添加字段func,value为函数自己
* what=L:表中添加字段activelines,表示函数的有效行(排除空行、只包含注释的行)
For instance, the expression debug.getinfo(1,"n").name returns a name
for the current function, if a reasonable name can be found, and the
expression debug.getinfo(print) returns a table with all available
information about the print function
* debug.getinfo(1,"n").name:返回表中name对应的值(函数的名字)
* debug.getinfo(print):返回print函数的表信息
示例
huli@hudeMacBook-Pro lua % cat f.lua
function fun()
for key,value in pairs(debug.getinfo(0)) do print(key,value) end
print()
for key,value in pairs(debug.getinfo(1)) do print(key,value) end
print()
for key,value in pairs(debug.getinfo(2)) do print(key,value) end
end
fun()
-- 运行脚本
huli@hudeMacBook-Pro lua % lua f.lua
name getinfo --函数的名称
ntransfer 0
source =[C] --函数定义的位置:定义在字符串中(如c函数)、文件中(以@开头的文件)
namewhat field
currentline -1
func function: 0x10ebb9d20
istailcall false
ftransfer 0
short_src [C]
lastlinedefined -1
linedefined -1
nparams 0 --函数参数的个数
isvararg true --函数参数是否可变
what C --函数的类型:可为C、lua、main
nups 0 --函数使用的外部局部变量(upvalue)的个数
name fun --调用getinfo的函数名称
ntransfer 0
source @f.lua --fun函数定义在文件中(f.lua)
namewhat global
currentline 5
func function: 0x600001620cf0
istailcall false
ftransfer 0
short_src f.lua
lastlinedefined 9
linedefined 1
nparams 0
isvararg false
what Lua
nups 1
ntransfer 0
source @f.lua
namewhat
currentline 11
func function: 0x600001620c60
istailcall false
ftransfer 0
short_src f.lua
lastlinedefined 0
linedefined 0
nparams 0
isvararg true
what main
nups 1
debug.getlocal([thread,] f, local):获取函数内部设置的局部变量、调用该函数的函数的局部变量
This function returns the name and the value of the local
variable with index local of the function at level f of the
stack. This function accesses not only explicit local variables,
but also parameters and temporary values.
* 返回索引为local的局部变量的name、value
* 该函数可获取局部变量、参数、临时变量
The first parameter or local variable has index 1, and so on,
following the order that they are declared in the code, counting
only the variables that are active in the current scope of the function.
* 第一个局部变量的索引为1,按照申明顺序依次索引
* 只统计在当前作用域内有效的局部变量
Compile-time constants may not appear in this listing, if they were
optimized away by the compiler. Negative indices refer to vararg arguments;
-1 is the first vararg argument.
* 负数表示参数:-1表示第一个参数
The function returns fail if there is no variable with the given index,
and raises an error when called with a level out of range. (You can call
debug.getinfo to check whether the level is valid.)
* 如果没有对应的局部变量,会报错
Variable names starting with '(' (open parenthesis) represent variables with no
known names (internal variables such as loop control variables, and variables from
chunks saved without debug information).
* 以"("开头的变量名表示没有显示的名称
The parameter f may also be a function. In that case, getlocal returns only the
name of function parameters.
* f可以是函数,表示获取指定函数的参数
debug.setlocal([thread,] level, local, value):设置函数的局部变量
This function assigns the value value to the local variable with
index local of the function at level level of the stack.
* 设置函数的局部变量,index是索引、level是函数所在的栈层次
The function returns fail if there is no local variable with the
given index, and raises an error when called with a level out of range.
You can call getinfo to check whether the level is valid.
* 如果没有局部变量,函数返回fail,
* 如果level超出有效范围,会抛出异常
Otherwise, it returns the name of the local variable
* 如果正常设置,会返回局部变量的名称
示例:主函数中修改局部变量
huli@hudeMacBook-Pro lua % cat f3.lua
local a=0
local b=0
print("主函数局部变量debug前")
print("a",a)
print("b",b)
debug.setlocal(1,1,1)
debug.setlocal(1,2,2)
print("\n主函数局部变量debug后")
print("a",a)
print("b",b)
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f3.lua
主函数局部变量debug前
a 0
b 0
主函数局部变量debug后
a 1
b 2
示例:在函数fun中get、set函数内、函数外的局部变量
huli@hudeMacBook-Pro lua % cat f2.lua
local a=0
local b=0
print("主函数局部变量debug前")
print('a',a)
print('b',b)
function fun()
local i=0
local j=0
print("\n函数局部变量debug前")
print("debug.getlocal(1,1)", debug.getlocal(1, 1))
print("debug.getlocal(1,2)", debug.getlocal(1, 2))
debug.setlocal(1,1,1) --设置1层(fun函数)的局部变量,index=1的局部变量值为4
debug.setlocal(1,2,2) --设置1层(fun函数)的局部变量,index=1的局部变量值为4
debug.setlocal(2,1,3) --设置2层(调用fun函数的main函数)的局部变量,index=1的局部变量值为4
debug.setlocal(2,2,4) --设置2层调用fun函数的main函数)的局部变量,index=2的局部变量值为4
print("\n函数局部变量debug后:")
print("debug.getlocal(1,1)", debug.getlocal(1,1))
print("debug.getlocal(1,2)", debug.getlocal(1,2))
end
print()
--print(debug.setlocal(2,1,1))
--print(debug.setlocal(2,2,2))
fun()
print("\n主函数局部变量debug后")
print("a",a)
print("b",b)
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f2.lua
主函数局部变量debug前
a 0
b 0
函数局部变量debug前
debug.getlocal(1,1) i 0
debug.getlocal(1,2) j 0
函数局部变量debug后:
debug.getlocal(1,1) i 1
debug.getlocal(1,2) j 2
主函数局部变量debug后
a 3
b 4
getupvalue(f, up):返回指定函数f、索引为up的upvalue的name、value
This function returns the name and the value of the
upvalue with index up of the function f. The function
returns fail if there is no upvalue with the given index.
* 返回指定函数f的索引为up的upvalue(外部变量)的name、value
* 如果没有返回nil
For Lua functions, upvalues are the external local variables
that the function uses, and that are consequently included
in its closure.
* 如果是lua函数,upvalues是函数使用的外部局部变量
For C functions, this function uses the empty string ""
as a name for all upvalues.
* 如果是c函数,所有upvalue的name都是""
Variable name '?' (interrogation mark) represents variables
with no known names (variables from chunks saved without
debug information).
* ?表示变量没有显示的名称
setupvalue(f, up, value):设置函数f、索引为up的值为value
This function assigns the value value to the upvalue with index up of the
function f. The function returns fail if there is no upvalue with the given
index. Otherwise, it returns the name of the upvalue.
* 设置函数f、索引up的upvalue的值为value,设置成功返回该局部变量的name
* 如果没有该变量,返回nil
示例
huli@hudeMacBook-Pro lua % cat f4.lua
local a=0
local b=0
function fun()
a=a+1
b=b+1
end
print("调用setupvalue前")
print(debug.getupvalue(fun,1))
print(debug.getupvalue(fun,2))
debug.setupvalue(fun,1,10)
debug.setupvalue(fun,2,20)
print("\n调用setupvalue后")
print(debug.getupvalue(fun,1))
print(debug.getupvalue(fun,2))
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f4.lua
调用setupvalue前
a 0
b 0
调用setupvalue后
a 10
b 20
示例
huli@hudeMacBook-Pro lua % cat f5.lua
local a=0
local b=0
function fun()
local i=0
local j=0
print(debug.getlocal(1,1,1))
print(debug.getlocal(1,1,2))
a=a+1
b=b+1
print(debug.getupvalue(fun,2))
print(debug.getupvalue(fun,3))
end
print("调用setupvalue前")
fun()
print("\n调用setupvalue")
print(debug.setupvalue(fun,2,10))
print(debug.setupvalue(fun,3,20))
print("\n调用setupvalue后")
fun()
print("\n主函数调用getupvalue")
print(debug.getupvalue(fun,2))
print(debug.getupvalue(fun,3))
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f5.lua
调用setupvalue前
i 0
i 0
a 1
b 1
调用setupvalue
a
b
调用setupvalue后
i 0
i 0
a 11
b 21
主函数调用getupvalue
a 11
b 21
debug可以将其他协程作为入参,调试其他协程
示例
huli@hudeMacBook-Pro lua % cat f6.lua
co = coroutine.create(
function()
local i=0
print(debug.getlocal(co,1,1))
error("错误函数")
end
)
coroutine.resume(co)
print(debug.traceback(co))
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f6.lua
i 0
stack traceback:
[C]: in function 'error'
f6.lua:5: in function <f6.lua:2>
钩子函数:发生指定的事件(call、return、line、count)时触发调用
call:函数被调用时出发
return:函数返回时出发
line:函数新的一行执行时触发
count:函数执行完指定数量(count)指令后触发
gethook([thread]):获取钩子函数
Returns the current hook settings of the thread, as three values:
the current hook function, the current hook mask, and the current
hook count, as set by the debug.sethook function.
* 返回当前线程的钩子函数,共有3个返回值:钩子函数、mask、count
* 这些参数是sethook设置的
Returns fail if there is no active hook
* 如果没有钩子函数,返回失败
sethook([thread,] hook, mask, count):设置钩子函数
Sets the given function as the debug hook.
* 将指定的函数设置为钩子函数
The string mask and the number count describe when the hook
will be called. The string mask may have any combination of
the following characters, with the given meaning:
'c': the hook is called every time Lua calls a function;
'r': the hook is called every time Lua returns from a function;
'l': the hook is called every time Lua enters a new line of code.
* mask、count值设置
* c:每次调用函数的时候触发
* r:每次返回的时候触发
* l:每次执行新的一行时触发
Moreover, with a count different from zero, the hook is called also
after every count instructions.
* count大于0时,每执行count次指令时触发
When called without arguments, debug.sethook turns off the hook.
* sethook不携带参数时,会关闭钩子函数
When the hook is called, its first parameter is a string describing
the event that has triggered its call: "call", "tail call", "return",
"line", and "count". For line events, the hook also gets the new line
number as its second parameter. Inside a hook, you can call getinfo
with level 2 to get more information about the running function.
(Level 0 is the getinfo function, and level 1 is the hook function.)
* 当钩子函数触发时,第一个参数是描述触发钩子函数的事件(call、return、line、count)
* line事件还有第2个参数:新的行号
* 在钩子函数内,还可以使用getinfo(level=2 )获取正在运行的函数信息
示例
huli@hudeMacBook-Pro lua % cat f8.lua
function fun()
print('fun函数被调用了')
end
debug.sethook(fun,'c')
print("\n主函数调用fun")
fun()
-- 执行脚本
huli@hudeMacBook-Pro lua % lua f8.lua
fun函数被调用了
主函数调用fun
fun函数被调用了
fun函数被调用了
fun函数被调用了