Reputation: 2544
say I've a project folder like:
mxn:lab axn$ tree .
.
├── lib
│ ├── a.lua
│ └── b.lua
└── main.lua
where main.lua
:
require("lib.a")
and in a.lua
I just use the string "b"
, trying to tell lua - find a file whose name is b.lua
in the same folder of a.lua
first:
require("b")
and b.lua
:
print('b loaded!')
then I run command lua main.lua
and get error:
[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]: ?
I know solutions like package.path = package.path..';'..'lib/?.lua'
, but what if the structure changes to:
.
├── foo
│ └── lib
│ ├── a.lua
│ └── b.lua
└── main.lua
I don't want to modify the package.path again. No matter what the structrue is, require("b")
in a.lua
will always make lua to search b
in the same folder of a.lua
first.
Upvotes: 4
Views: 1684
Reputation: 7056
Generally speaking, you shouldn't do that. Using .
in require is meant for submodules, but neither a
nor b
are submodules of some lib
module; that's just where you're putting your modules to keep them organized.
package.path
exists for exactly this reason. You can just do something like this:
package.path = './lib/?.lua;./lib/?/init.lua;' .. package.path
And Lua will now search for modules in the lib
directory (in addition to where it usually does).
You can also use the LUA_PATH
environment variable to do this before even starting Lua.
Otherwise, if you really don't want to use the "proper" way of using package.path
, try putting this at the top of a.lua
:
print(...)
and it should print something like
lib.a ./lib/a.lua
That should get you to how you want it to work.
Upvotes: 3
Reputation: 473447
Rather than rewriting require
and affecting the behavior of all code everywhere, it's best to create a special function for this purpose:
--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
Note that this function forces you to separate the local path from the name of the module being required. The given local_path
is always expected to be local to the most recent nested call of require_local_path
. It is also expected to end in a /
directory separator character.
If you absolutely must give it a single string rather than a separate path, I'm sure you can write a version of this which splits the given module into a base name and a local path.
Upvotes: 2