Подтвердить что ты не робот

Загружать 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, если это имеет значение.

4b9b3361

Ответ 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