Search code examples
lualuajit

How to read a data file at a package path on Lua 5.1


How to read a data file at a package path on Lua 5.1?

What I'm looking for is something like a io.read but at the package directory instead of the working directory (arg[0]), and without using hardcoded absolute paths. That would be something like dofile does, but without running the code, only reading it as a string.

Example:

I have a test folder, the current working directory of the test.lua script.

There's a package luapackage in another folder, somewhere specified at the LUA_PATHenviroment variable.

luapackage can:

  • require("luapackage.other_module");
  • dofile("other_module.lua").

But luapackage can't do:

  • io.read("data.txt")
  • io.read("luapackage/data.txt")

Sample structure:

+-test/
  |
  +-test.lua

+-luamodule/
  |
  +-data.txt
  |
  +-luamodule.lua
  |
  +-other_module.lua

For this example, test.lua only requires luamodule:

-- test.lua
local luamodule = require("luamodule")

And luamodule needs to read its modules and data files:

-- luamodule.lua
local other_module= dofile("other_module.lua") -- works
-- local other_module= require("luamodule.other_module") -- also works

local data = io.open("data.txt") -- fails
-- local data = io.open("luamodule/data.txt") -- also fails

It doesn't work because it searches for the file at the working directory (test) and not the package directory.

If I place a copy of the package at running script's folder, io.read(luapackage/data.txt) is possible. But every script would have to carry its own local copy of luapackage.

Note: I'm looking for a Lua solution, avoiding binary packages that could compromise cross-compatibility.


Solution

  • You can use debug.getinfo(1,"S").source to get the location of the current (module) file. Replace luamodule.lua with data.txt, remove leading @, and you should get the path you need.