2

I'm struggling to figure out how to structure and then use internal dependencies in a Lua library I'm writing.

I've defined my library like this:

./alib.lua
./alib/adependency.lua

And the code:

-- File: ./alib.lua
local ad = require "alib.adependency"
module( "alib")
return {}

-- File: ./alib/adependency.lua
module( "adependency" )
return {}

This works a treat:

$ lua alib.lua
<no output>

Now let's "add" this library into another app:

./anapp.lua
./lib/alib.lua
./lib/alib/adependency.lua

And the new code:

-- File: ./anapp.lua
local alib = require "lib.alib"
local print = print
module( "anapp")
print "Hello"

Try to run it:

$ lua anapp.lua
lua: ./lib/alib.lua:2: module 'alib.adependency' not found:
    no field package.preload['alib.adependency']
    no file './alib/adependency.lua'
    no file '/usr/local/share/lua/5.1/alib/adependency.lua'
    no file '/usr/local/share/lua/5.1/alib/adependency/init.lua'
    no file '/usr/local/lib/lua/5.1/alib/adependency.lua'
    no file '/usr/local/lib/lua/5.1/alib/adependency/init.lua'
    no file '/usr/share/lua/5.1/alib/adependency.lua'
    no file '/usr/share/lua/5.1/alib/adependency/init.lua'
    no file './alib/adependency.so'
    no file '/usr/local/lib/lua/5.1/alib/adependency.so'
    no file '/usr/lib/x86_64-linux-gnu/lua/5.1/alib/adependency.so'
    no file '/usr/lib/lua/5.1/alib/adependency.so'
    no file '/usr/local/lib/lua/5.1/loadall.so'
    no file './alib.so'
    no file '/usr/local/lib/lua/5.1/alib.so'
    no file '/usr/lib/x86_64-linux-gnu/lua/5.1/alib.so'
    no file '/usr/lib/lua/5.1/alib.so'
    no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
    [C]: in function 'require'
    ./lib/alib.lua:2: in main chunk
    [C]: in function 'require'
    anapp.lua:2: in main chunk
    [C]: ?

Oh dear. Now I make a manual edit inside the library:

-- File: ./lib/alib.lua
-- local ad = require "alib.adependency" -- Doesn't work
local ad = require "lib.alib.adependency" -- Works
module( "alib")
return {}

And it works:

$ lua anapp.lua
Hello

It seems that Lua's require() relates paths relative to the ultimate script being run by Lua, not the script in which the require() is called.

Surely you don't have to manually fix the internal paths require()d inside of a Lua library every time you add one to your project... And I don't see how this can work from a unit test perspective either. What am I doing wrong?

Alex Dean
  • 15,575
  • 13
  • 63
  • 74

1 Answers1

2

I think the cleanest solution is to leave your library as it was, and then make whomever is using your library responsible for configuring the package.path correctly. In your setup that means the application should add the lib folder to the path:

package.path = './lib/?.lua;' .. package.path

See also related questions like Is there a better way to require file from relative path in lua as well as the manual for more about the path.

Community
  • 1
  • 1
Supr
  • 18,572
  • 3
  • 31
  • 36