按相对路径加载Lua文件

按相对路径加载Lua文件,lua,require,coronasdk,Lua,Require,Coronasdk,如果我有这样的文件结构: ./main.lua ./mylib/mylib.lua ./mylib/mylib-utils.lua ./mylib/mylib-helpers.lua ./mylib/mylib-other-stuff.lua require 'lib.foo.bar' 从main.lua可以使用完整路径require('mylib.mylib')加载文件mylib.lua。但是在mylib.lua内部我还想加载其他必要的模块,我不想总是指定完整路径(例如mylib.myli

如果我有这样的文件结构:

./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua
require 'lib.foo.bar'
main.lua
可以使用完整路径
require('mylib.mylib')
加载文件
mylib.lua
。但是在
mylib.lua内部
我还想加载其他必要的模块,我不想总是指定完整路径(例如
mylib.mylib utils
)。如果我决定移动文件夹,我将进行大量搜索和替换。有没有办法只使用路径的相对部分

UPD。我正在将Lua与Corona SDK一起使用,如果有必要的话。

您可以这样做

package.path = './mylib/?.lua;' .. package.path

然后


有一种方法可以推断文件的“本地路径”(更具体地说,是用来加载文件的字符串)

如果您需要
lib.foo.bar
中的文件,您可能会执行以下操作:

./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua
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
,此文件的
文件夹将自动更新。

在Conky的lua环境下,我已设法将我的
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

奇怪。我已经尝试更改了
package.path
,并认为我做错了什么,因为它说
没有字段package.preload['mylib-utils']
没有文件。/mylib/mylib-utils.lua'
。但是我在Corona SDK中使用Lua,可能它在加载文件方面有一些特殊性。如果cwd已更改(即,您从另一个程序/路径运行脚本),这将不起作用。如果修改后的
require()
本身调用
require(),这也将不起作用
,希望它能正常工作。谢谢,这对加载文件起到了作用。但当我访问模块的公共属性时,我仍然需要指定完整路径(例如
lib.foo.bar.some_value
),这与加载文件无关;它只是反映了您选择如何构建Lua。您可以(例如)针对每个require返回一个表,并将其存储在本地变量中:
local baz=require(此文件的folderofthis..'baz')
,然后执行
baz。一些值
Cool,我不知道
外部函数是用于要求文件的字符串。@kikito但它强制使用完整的命名空间路径,即使在同一库的文件之间也是如此。如果我声明
mylib.var1
,那么在
mylib utils
中,我必须指定
一些.long.path.mylib.var1
,这非常尴尬。我想,我会坚持使用一个包含所有内容的目录。它无法维护,但可以使用。@RockeR:你确定你读对了我的评论吗?它精确地处理了这个问题:它允许您执行
baz.some_value
而不是
lib.foo.bar.some_value
。有关使用环境变量的方法,请参阅.Corona SDK。。。在2020年读起来很可怕。