Lua 嵌套的需求路径
Lua Nested Require Path
我正在编写一个工具来解析 lua 其他用户创建的插件。关于该插件的唯一保证是它在已知目录中有一个 data.lua 文件。在里面,用户可以自由地做任何他们想做的事情。这个特定的插件使用 require 加载一个文件,然后该文件加载另一个文件。两者都是相对路径,但第二个是相对于第一个文件的位置。
- data.lua
- foo/bar.lua
- foo/baz.lua
data.lua:
require("foo.bar")
foo/bar.lua:
require("baz")
当我尝试执行 data.lua 时,当 foo/bar 时出现错误。lua 试图要求 "baz"。 None 它尝试的路径是 ./foo/.
知道如何解决这个问题吗?我可以找到任何专门关于这种情况的文档,似乎我需要将 /foo/ 硬编码到路径中,但我事先并不知道。这似乎应该是自动的,是我缺少设置还是我 运行 lua 的错误版本?我正在使用 NLua 4.0
谢谢
您可以通过更改 package.path
变量来改变 require 的搜索行为。
package.path
上的资源:
将 foo 文件夹添加到搜索位置的示例:
package.path = package.path .. ';./foo/?.lua'
?
字符将是传递给 require 的字符串所在的位置。
或者,您可以将要加载的默认文件添加到 package.path
:
package.path = package.path .. ';./nested_require.lua'
然后在此文件中定义您想要的行为。您可以使用全局变量 _REQUIREDNAME
来引用传递给 require 函数的值。
可以在页面底部找到此方法的文档:https://www.lua.org/pil/8.1.html
我使用 node-lua 测试了这个脚本,它解决了我的问题!
https://gist.github.com/hoelzro/1299679
相关代码:
local oldrequire = require
function require(modname)
local regular_loader = package.loaders[2]
local loader = function(inner)
if string.match(modname, '(.*)%.') then
return regular_loader(string.match(modname, '(.*)%.') .. '.' .. inner)
end
end
table.insert(package.loaders, 1, loader)
local retval = oldrequire(modname)
table.remove(package.loaders, 1)
return retval
end
为了让它与 Lua 一起工作 5.2 将 package.loaders 的所有用途更改为 package.searchers。
此外,如果您想覆盖全局 require 函数,您还需要此代码段:
_G.require = require
我正在编写一个工具来解析 lua 其他用户创建的插件。关于该插件的唯一保证是它在已知目录中有一个 data.lua 文件。在里面,用户可以自由地做任何他们想做的事情。这个特定的插件使用 require 加载一个文件,然后该文件加载另一个文件。两者都是相对路径,但第二个是相对于第一个文件的位置。
- data.lua
- foo/bar.lua
- foo/baz.lua
data.lua:
require("foo.bar")
foo/bar.lua:
require("baz")
当我尝试执行 data.lua 时,当 foo/bar 时出现错误。lua 试图要求 "baz"。 None 它尝试的路径是 ./foo/.
知道如何解决这个问题吗?我可以找到任何专门关于这种情况的文档,似乎我需要将 /foo/ 硬编码到路径中,但我事先并不知道。这似乎应该是自动的,是我缺少设置还是我 运行 lua 的错误版本?我正在使用 NLua 4.0
谢谢
您可以通过更改 package.path
变量来改变 require 的搜索行为。
package.path
上的资源:
将 foo 文件夹添加到搜索位置的示例:
package.path = package.path .. ';./foo/?.lua'
?
字符将是传递给 require 的字符串所在的位置。
或者,您可以将要加载的默认文件添加到 package.path
:
package.path = package.path .. ';./nested_require.lua'
然后在此文件中定义您想要的行为。您可以使用全局变量 _REQUIREDNAME
来引用传递给 require 函数的值。
可以在页面底部找到此方法的文档:https://www.lua.org/pil/8.1.html
我使用 node-lua 测试了这个脚本,它解决了我的问题!
https://gist.github.com/hoelzro/1299679
相关代码:
local oldrequire = require
function require(modname)
local regular_loader = package.loaders[2]
local loader = function(inner)
if string.match(modname, '(.*)%.') then
return regular_loader(string.match(modname, '(.*)%.') .. '.' .. inner)
end
end
table.insert(package.loaders, 1, loader)
local retval = oldrequire(modname)
table.remove(package.loaders, 1)
return retval
end
为了让它与 Lua 一起工作 5.2 将 package.loaders 的所有用途更改为 package.searchers。
此外,如果您想覆盖全局 require 函数,您还需要此代码段:
_G.require = require