2

If I have two scripts that reference each other on the same directory

A/
   foo.lua
   bar.lua

foo.lua

require "bar"

bar.lua

print "It worked"

then running the lua executable from the same folder works

cd A; lua foo.lua

but running the interpreter from another folder fails with a "module 'bar' not found" message

cd A/..; lua A/foo.lua

Is there a way to have my relative imports not depend on the current working directory? For example, in batch files I can setup my paths to be relative to dirname $0.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • possible duplicate of [Is there a better way to require file from relative path in lua](http://stackoverflow.com/questions/5761229/is-there-a-better-way-to-require-file-from-relative-path-in-lua) – finnw Jul 30 '12 at 15:33

2 Answers2

2

The usual way to do this is to update package.path to contain the parent of A (or put A on the path). Then use require and refer to the modules as A.bar and A.foo

See the manual entry on require

It is possible to find the directory using debug.getinfo but using the debug module in applications is not a great idea, and not necessary in this case.

See this related SO question -- use package.path.

Community
  • 1
  • 1
Doug Currie
  • 40,708
  • 1
  • 95
  • 119
2

The main issue is that package.path doesn't consider the directory the running script is in. While Doug's solution works this can become tedious if you have to keep adding

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

to scripts you plan on running from a different working directory. What you can do to make it easier is create a module that automatically adds the running script's directory to package.path when you require it. This module would reside in one of the default locations listed in package.path so it can be found.

-- moduleroot.lua
local moduleroot = arg and arg[0]
if moduleroot then
  local path = moduleroot:match [[^(.+[\/])[^\/]+$]]
  if path and #path > 0 then
    package.path = path..'?.lua;'..package.path
    package.cpath = path..'?.dll;'..package.cpath
    return path
  end
end

-- foo.lua
require "moduleroot"
require "bar"

In fact, this is a common enough problem that Penlight includes a convenience facility for handling this: pl.app.require_here.

greatwolf
  • 20,287
  • 13
  • 71
  • 105