11

我将回到这里的基础知识,但在 Lua 中,您可以像这样定义一个表:

myTable = {}
myTable [1] = 12

打印表引用本身会带回一个指向它的指针。要访问它的元素,您需要指定一个索引(即,就像您使用数组一样)

print(myTable )    --prints pointer
print(myTable[1])  --prints 12

现在函数是一个不同的故事。您可以像这样定义和打印函数:

myFunc = function() local x = 14 end     --Defined function
print(myFunc)                            --Printed pointer to function

有没有办法访问已定义函数的主体。我正在尝试组合一个小型代码可视化器,并希望使用特殊函数/变量“播种”给定函数,以允许可视化器将自身“挂钩”到代码中,我需要能够重新定义该函数变量或字符串。

4

4 回答 4

11

在普通 Lua 中无法访问给定函数的主体源代码。源代码在编译为字节码后被丢弃。

注意顺便说一句,该函数可以在运行时使用类似加载字符串的工具来定义。

部分解决方案是可能的 - 取决于您实际想要实现的目标。

您可以从调试库中获取源代码位置——如果启用了调试库并且调试符号没有从字节码中剥离。之后,您可以加载实际的源文件并从那里提取代码。

您可以使用所需的元数据手动装饰您感兴趣的功能。请注意,Lua 中的函数是有效的表键,因此您可以创建函数到元数据表。您可能希望将此表设为弱键,这样就不会阻止 GC 收集函数。

如果您需要分析 Lua 代码的解决方案,请查看Metalua

于 2009-02-02T21:35:39.857 回答
5

查看调试库中的Lua Introspective Facilities

调试库中主要的内省函数是 debug.getinfo 函数。它的第一个参数可能是函数或堆栈级别。当您为某个函数 foo 调用 debug.getinfo(foo) 时,您会得到一个包含有关该函数的一些数据的表。该表可能具有以下字段:

我认为你想要的领域是 func 。

于 2009-02-02T19:52:18.847 回答
5

使用调试库是您唯一的选择。使用它,您可以获得字符串(如果函数是在使用“loadstring”加载的块中定义的)或定义函数的文件的名称;以及函数定义开始和结束的行号。请参阅文档

在我目前的工作中,我们对 Lua 进行了修补,以便它甚至为您提供函数开始和结束的列号,因此您可以使用它来获取函数源。该补丁不是很难复制,但我认为我不会被允许在这里发布它:-(

于 2009-02-04T10:04:22.077 回答
0

您可以通过为每个函数创建一个环境(请参阅setfenv)并使用全局(相对于局部)变量来完成此操作。在函数执行后,函数中创建的变量将出现在环境表中。

env = {}
myFunc = function() x = 14 end
setfenv(myFunc, env)
myFunc()
print(myFunc)    -- prints pointer
print(env.x)     -- prints 14

或者,您可以使用调试库

> myFunc = function() local x = 14 ; debug.debug() end
> myFunc()
> lua_debug> _, x = debug.getlocal(3, 1)
> lua_debug> print(x) -- prints 14

使用钩子函数检索局部变量可能对您更有用,而不是显式进入调试模式(即添加 debug.debug() 调用)

Lua C API 中还有一个调试接口

于 2009-02-02T19:09:52.350 回答