web-dev-qa-db-ja.com

相対パスで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。必要に応じて、Corona SDKでLuaを使用しています。

33
RocketR

ファイルの「ローカルパス」(より具体的には、ファイルのロードに使用された文字列)を推測する方法があります。

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が自動的に更新されます。

34
kikito

できるよ

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
15
Seth Carnegie

ConkyのLua環境では、(同じディレクトリに)_common.lua_をrequire(".common")として含めることができました。先頭のドット_._文字に注意してください。

0
Vladius

次のスニペットを使用しています。 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
0
jcai