我一直在尝试创建一个函数,一旦某个函数被调用,它就会运行一个事件/函数。我希望用法是这样的:
local a = nil
a = hookfunction(print, function() -- When print() is called...
warn("print(...) called.")
return nil
end)
Run Code Online (Sandbox Code Playgroud)
我知道有一个 debug.sethook() 函数,但我不太知道如何使用它。
有两种方法可以做到这一点,但每种方法都有一些您需要处理的陷阱。
一种方法是使用monkeypatching。这会将打印函数更改为另一个函数,该函数将执行您需要的操作,然后调用原始函数。
像这样的东西:
local origprint = print;
(_G or _ENV).print = function(...)
io.write("print is called\n")
return origprint(...)
end
print("foo", 1)
Run Code Online (Sandbox Code Playgroud)
这个选项的主要缺陷是,如果某个组件在进行猴子补丁之前保存了值print,那么它的后续使用将不会受到补丁的影响。
另一种选择是使用调试挂钩:
debug.sethook(function()
local info = debug.getinfo(2)
if info.name then
io.write(info.name, " is called\n")
end
end, "c")
function foo()
print("do something")
end
foo()
Run Code Online (Sandbox Code Playgroud)
这应该打印:
foo is called
print is called
do something
Run Code Online (Sandbox Code Playgroud)
这种方法的主要缺陷是它不能保证它会按照您的预期输出函数名称,因为这些值可能与它们的不同名称/容器相关联。
例如,这将打印a is called:
local a = print
a("do something")
Run Code Online (Sandbox Code Playgroud)
这将打印? is called:
local a = {print}
a[1]("do something")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |