Загрузка 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'). Но внутри!--2--> Я также хотел бы загрузить другие необходимые модули, и я не чувствую, что всегда указываю полный путь (например,mylib.mylib-utils). Если я когда-нибудь решу переместить папку, у меня будет много поиска и замены. Есть ли способ использовать только относительную часть пути?

UPD. Я использую Lua с Corona SDK, если это вопросы.

4 ответов


существует способ вывода "локального пути" файла (более конкретно, строки, которая использовалась для загрузки файла).

Если вам требуется файл внутри lib.foo.bar, вы можете делать что-то вроде этого:

require 'lib.foo.bar'

затем вы можете получить путь к файлу в качестве первого элемента (и только) ... переменная, когда вы находитесь вне всех функций. Другими словами:

-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'

теперь, чтобы получить "папку", Вам нужно удалить имя файла. Самый простой способ использование match:

local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'

и вот оно. Теперь вы можете добавить эту строку к другим именам файлов и использовать ее для требования:

require(folderOfThisFile .. 'baz')     -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')

если вы двигаетесь bar.lua вокруг folderOfThisFile будет автоматически обновлена.


можно сделать

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

в среде Lua Conky мне удалось включить мой common.lua (в том же каталоге), что и require(".common"). Обратите внимание на ведущую точку . символ.


Я использую следующий фрагмент. Он должен работать как для файлов, загруженных с 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