Lua 嵌套 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" 时会遇到错误。它尝试的路径都不是 ./foo/ 中的任何一个。

有什么办法可以解决这个问题吗?我找不到具体针对这种情况的文档,好像需要将 /foo/ 硬编码到路径中,但我事先不知道它。这似乎是应该自动完成的事情,我缺少设置或者是运行了错误的 lua 版本吗?我使用的是 NLua 4.0

谢谢

点赞
用户7396148
用户7396148

你可以通过改变 package.path 变量来改变 require 的搜索行为。

package.path 的资源:

https://www.lua.org/manual/5.3/manual.html#pdf-package.path

http://lua-users.org/wiki/PackagePath

例如,将 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

2018-12-23 03:12:58
用户350964
用户350964

我使用了 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
2018-12-23 16:36:36