1

是否可以使用 lua 调试库检测变量的值何时发生变化。类似于回调函数的东西,它会提供详细信息,例如更改值的函数、先前的值等。这样的事情可能吗?

我阅读了有关钩子的信息,但我不确定钩子是否可以设置为变量。

4

2 回答 2

2

您可以在 Lua 中通过使用元表并保留“代理”表并使用 __newindex 函数调用来检测添加变量的尝试在一定程度上做到这一点。

这在“跟踪表访问”部分的 Lua 编程一书中有所介绍:

http://www.lua.org/pil/13.4.4.html

另见
http://www.gammon.com.au/forum/?id=10887

于 2012-08-13T20:43:14.177 回答
2

如果您不介意使用调试器,那么某些调试器允许您设置 Watch 表达式,当表达式中的条件为真时将触发该表达式。我将展示如何在MobDebug中完成此操作(它使用 lua 调试库,但据我所知,没有直接的方法来检测变量更改)。

假设我们有一个start.lua像下面这样的脚本,并且想要检测foo值 2 的位置:

print("Start")
local foo = 0
for i = 1, 3 do
  local function bar()
    print("In bar")
  end
  foo = i
  print("Loop")
  bar()
end
print("End")
  1. 下载mobdebug.lua并使其可用于您的脚本(最简单的方法是将其与您的脚本一起放入文件夹中)。
  2. lua -e "require('mobdebug').listen()"使用命令启动服务器。
  3. lua -e "require('mobdebug').loop()"使用命令启动客户端。
  4. 您将在服务器窗口中看到提示:'>'。键入load start.lua以加载脚本。
  5. 键入step,然后step再次键入。你会看到“Paused at file start.lua line 3”。
  6. 让我们看看它的价值foo是多少。键入eval foo,您应该会看到 0。
  7. 现在我们可以设置我们的手表了。键入setw foo == 2。你可以在 setw 命令之后指定任何 Lua 表达式;当条件被评估为真时,脚本的执行将停止。
  8. 使用“运行”命令继续执行脚本。
  9. 手表现在触发,它将向您显示如下消息:“Paused at file start.lua line 8 (watch expression 1: [foo == 2])”。这意味着前面的表达式将值更改foo为 2 并且执行在第 8 行停止。然后您可以检查您的脚本和当前值(您可以使用“eval”和“exec”命令运行任何 Lua 代码在您的脚本环境中评估)以查找触发更改的原因。

这种方法的好处是您不仅可以监视表值,还可以指定任何表达式。主要缺点是您的脚本在调试器下运行,并且在每一步之后都会评估表达式,这可能会变得非常慢。

于 2012-08-13T21:50:23.600 回答