从Lua中的dofile调用回主文件

假设我有两个文件:

一个名为 mainFile.lua:

function altDoFile(name)
    dofile(debug.getinfo(1).source:sub(debug.getinfo(1).source:find(".*\\")):sub(2)..name)
end

altDoFile("libs/caller.lua")

function callBack()
    print "called back"
end

doCallback()

另一个名为 caller.lua,位于 libs 文件夹中:

function doCallback()
    print "performing call back"
    _G["callBack"]()
end

运行第一个文件的输出为:

"performing call back"

然后什么都没有了,我丢失了一行!

为什么 callBack 从未被执行?这是预期行为吗,我怎么解决?

从字符串调用函数的事实很重要,因此无法更改它。

更新: 我已经进行了进一步测试,_G["callBack"]确实会解析为一个函数(type()),但它仍然不会被调用。

点赞
用户415823
用户415823

为什么不直接使用dofile呢?

看起来altDoFile的目的是通过替换正在运行脚本的文件名而创建绝对路径,以便调用你想要的脚本。在这种情况下,caller.lua的路径是一个相对路径,所以你不需要改变任何内容来让Lua加载文件。

将你的代码重构为这个样子:

dofile("libs/caller.lua")

function callBack()
    print "called back"
end

doCallback()

似乎可以得到你想要的结果:

$ lua mainFile.lua
performing call back
called back

只是作为一个旁白,如果路径不包含\字符,altDoFile会抛出错误。Windows使用反斜杠作为路径名,但其他操作系统如Linux和MacOS不会。

在我的情况下,在Linux上运行你的脚本会抛出错误,因为string.find返回的是nil而不是索引。

lua: mainFile.lua:2: bad argument #1 to 'sub' (number expected, got nil)

如果你需要知道主脚本的工作路径,为什么不将其作为命令行参数传递:

C:\LuaFiles> lua mainFile.lua C:/LuaFiles

然后在Lua中:

local working_path = arg[1] or '.'
dofile(working_path..'/libs/caller.lua')
2012-07-04 00:06:24
用户151501
用户151501

如果你只想要能够回到上一级目录,你也可以修改加载器

 package.path = ";../?.lua" .. package.path;

这样,你可以通过执行以下命令来运行你的文件:

require("caller")
2012-07-04 08:55:35
用户5569588
用户5569588
dofile "../Untitled/SensorLib.lua" --使用上层路径的库

祝好
K.
2015-11-16 22:25:07