如何使lua搜索模块与首先调用require的模块位于同一文件夹中?

如何使lua搜索模块与首先调用require的模块位于同一文件夹中?,lua,lua-5.1,Lua,Lua 5.1,假设我有一个项目文件夹,如: mxn:lab axn$ tree . . ├── lib │ ├── a.lua │ └── b.lua └── main.lua 其中main.lua: require("lib.a") print('b loaded!') 在a.lua中,我只是使用字符串“b”,试图告诉lua-首先在a.lua的同一文件夹中找到一个名为b.lua的文件: require("b") 和b.lua: require("lib.a") print('b loade

假设我有一个项目文件夹,如:

mxn:lab axn$ tree .
.
├── lib
│   ├── a.lua
│   └── b.lua
└── main.lua
其中
main.lua

require("lib.a")
print('b loaded!')
a.lua
中,我只是使用字符串
“b”
,试图告诉lua-首先在
a.lua
的同一文件夹中找到一个名为
b.lua
的文件:

require("b")
b.lua

require("lib.a")
print('b loaded!')
然后我运行命令
lua main.lua
并得到错误:

[Running] lua "/Users/axn/lab/main.lua"
lua: ./lib/a.lua:1: module 'b' not found:
    no field package.preload['b']
    no file './b.lua'
    no file '/usr/local/share/lua/5.1/b.lua'
    no file '/usr/local/share/lua/5.1/b/init.lua'
    no file '/usr/local/lib/lua/5.1/b.lua'
    no file '/usr/local/lib/lua/5.1/b/init.lua'
    no file './b.so'
    no file '/usr/local/lib/lua/5.1/b.so'
    no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
    [C]: in function 'require'
    ./lib/a.lua:1: in main chunk
    [C]: in function 'require'
    /Users/axn/lab/main.lua:1: in main chunk
    [C]: ?
我知道类似于
package.path=package.path.“;”的解决方案lib/?.lua'
,但如果结构更改为:

.
├── foo
│   └── lib
│       ├── a.lua
│       └── b.lua
└── main.lua

我不想再次修改package.path。无论结构是什么,
a.lua
中的
require(“b”)
总是让lua首先在
a.lua
的同一文件夹中搜索
b

而不是重写
require
并影响所有代码的行为,最好为此目的创建一个特殊函数:

--Utility function for Lua 5.1, which table.pack can do in 5.2+
function pack_params(...)
    return {n = select("#", ...), ...}
end

local curr_local_path = ""

function require_local_path(local_path, ...)
    --Store the old paths on the stack.
    local old_path = package.path
    local old_local_path = curr_local_path

    --Build the new search path and add it to the front of the package.path.
    curr_local_path = curr_local_path .. local_path
    package.path = "./" .. curr_local_path .. "?.lua;" .. package.path

    --Perform the require, storing the results temporarily.
    local rets = pack_params(require(...))

    --Fix the prior paths.
    package.path = old_path
    curr_local_path = old_local_path

    return unpack(rets, 1, rets.n)
end
请注意,此函数强制您将本地路径与所需模块的名称分开。给定的
local\u路径
总是期望是
require\u local\u路径
的最近嵌套调用的本地路径。它还应以
/
目录分隔符结尾


如果您必须给它一个字符串而不是单独的路径,我相信您可以编写一个版本,将给定的模块拆分为一个基本名称和一个本地路径。

一般来说,您不应该这样做。在require中使用
是为了子模块,但
a
b
都不是某些
lib
模块的子模块;这正是你放置模块的地方,以保持它们的有序性

正是因为这个原因而存在的。你可以这样做:

package.path='./lib/?.lua/lib/?/init.lua;'。。包路径
Lua现在将在
lib
目录中搜索模块(除了通常搜索的地方)

您甚至可以在启动LUA之前使用
LUA\u PATH
环境变量来执行此操作


否则,如果您确实不想使用“正确”的方式使用
package.path
,请尝试将其放在
a.lua
的顶部:

require("lib.a")
print('b loaded!')
打印(…) 它应该打印出这样的内容

lib.a ./lib/a.lua
这会让你知道你想要它如何工作