Загружать Lua файлы по относительному пути
Если у меня есть такая файловая структура, как это:
./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua
Из main.lua
файл mylib.lua
может быть загружен полным путем require('mylib.mylib')
. Но внутри mylib.lua
я также хотел бы загрузить другие необходимые модули, и я не чувствую, что всегда указываю полный путь (например, mylib.mylib-utils
). Если я когда-нибудь решит переместить папку, у меня будет много поиска и замены. Есть ли способ использовать только относительную часть пути?
UPD. Я использую Lua с Corona SDK, если это имеет значение.
Ответы
Ответ 1
Существует способ вывести "локальный путь" файла (более конкретно, строку, которая была использована для загрузки файла).
Если вам нужен файл внутри lib.foo.bar
, вы можете сделать что-то вроде этого:
require 'lib.foo.bar'
Затем вы можете получить путь к файлу в качестве первой переменной (и только) ...
, когда вы находитесь за пределами всех функций. Другими словами:
-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'
Теперь, чтобы получить "папку", вам нужно удалить имя файла. Самый простой способ - совпадение:
local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'
И у вас это есть. Теперь вы можете добавить эту строку к другим именам файлов и использовать для этого:
require(folderOfThisFile .. 'baz') -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')
Если вы перемещаете bar.lua
вокруг, folderOfThisFile
будет автоматически обновляться.
Ответ 2
Вы можете сделать
package.path = './mylib/?.lua;' .. package.path
или
local oldreq = require
local require = function(s) return oldreq('mylib.' .. s) end
Тогда
-- do all the requires
require('mylib-utils')
require('mylib-helpers')
require('mylib-other-stuff')
-- and optionally restore the old require, if you did it the second way
require = oldreq
Ответ 3
В среде Conky Lua мне удалось включить мой common.lua
(в том же каталоге) как require(".common")
. Обратите внимание на главный символ .
.
Ответ 4
Я использую следующий фрагмент. Он должен работать как для файлов, загружаемых с помощью require
, так и для файлов, вызываемых через командную строку. Затем используйте requireRel
вместо require
для тех, для которых вы хотите загрузить относительный путь.
local requireRel
if arg and arg[0] then
package.path = arg[0]:match("(.-)[^\\/]+$") .. "?.lua;" .. package.path
requireRel = require
elseif ... then
local d = (...):match("(.-)[^%.]+$")
function requireRel(module) return require(d .. module) end
end