我试图将一些由主模块和一些辅助模块组成的Lua库重新打包到Docker容器中。辅助模块保存在库的子文件夹中,以便从主文件导入为
require 'helpers/SomeHelper'
问题是:由于我希望Docker容器工作的方式,如果我可以从另一个工作文件夹调用这个库,那将非常有用。也就是说,我对主程序的调用就像是
th /app/main.lua
无论实际工作目录如何,我都站着。不幸的是,当工作目录与主文件所在的目录不同时,相对导入似乎失败了。
有什么方法可以配置LUA_PATH或任何其他机制来使这些导入正常工作?请注意,更改库本身的代码将是一个糟糕的解决方案,因为我没有开发它,我希望能够轻松地将其更新到更新的版本。
答案 0 :(得分:2)
如果您不关心工作目录,只需加载lfs
/ LuaFileSytem并使用lfs.chdir
( src_dir )
更改为源目录(可能会使用{保存当前工作目录) {3}} ( )
首先。)
您还可以扩展Lua的lfs.currentdir
,以便搜索这些额外的目录。搜索由search path驱动。要以支持所有通常支持的库布局的方式将目录/foo/bar/
添加到搜索中,请添加
/foo/bar/?.lua;/foo/bar/?/init.lua
至package.path
/foo/bar/?.so
(或其他OSen上的.dylib
或.dll
)至package.cpath
您可以使用多种方法来扩展路径。
一个效果很好的选项是设置LUA_PATH
/ LUA_CPATH
个环境变量。 (其中一个中的;;
序列将扩展为完整的默认路径。)这可以通过.profile
或其他设置脚本通过较早的export LUA_PATH="..."
或(如果从包装器启动)完成脚本)通过为该调用LUA_PATH="..." lua /foo/bar.lua
设置变量来内联。 (请注意,如果您在范围太宽的情况下导出此变量,则其他Lua脚本也会扩展其路径,并且可能会发现可能不兼容的Lua库。)
(您也可以从package.(c)path
手动修改LUA_INIT
。这样,您就无法独立停用LUA_INIT
或LUA_PATH
,但您可以全部使用Lua动态生成路径。)
第三个选项(在您的特定情况下可能最好)是将package.path
的扩展名放在主脚本的顶部,如
do
local dir = (arg[0]:match "^(.*)/$")
if dir then -- else cwd is . which works by default
package.path = dir.."/?.lua;"..dir.."/?/init.lua;"..package.path
package.cpath = dir.."/?.so;"..package.cpath
end
end
-- rest of your program goes here
使用Lua解释器运行脚本时,arg[0]
是脚本。所以这扩展了路径以包括程序的目录,无论它位于何处,它只会影响这个特定脚本/程序的搜索路径。
答案 1 :(得分:0)
您不应忘记并非所有模块都直接从FS加载。 例如。为了提高性能,有可能将文件读取/编译到内存然后 使用预加载表提供从内存加载模块的方法。 基本示例
--- preload code. It can be done by host application.
local FooUtils = function()
return {
print = function(...)
print("foo", ...)
end
}
end
local Foo = function()
local Utils = require "foo.utils"
return {
foo = function()
Utils.print"hello"
end
}
end
package.preload['foo.utils'] = FooUtils
package.preload['foo'] = Foo
--- main application
require "foo".foo()
在此示例中,假设FooUtils
和Foo
仅是已编译模块的示例。
例如。它可以像FooUtils = loadstring('path/to/utils.lua)
,它可以完成
即使在单独的Lua状态,然后用于任何其他。
重要的是要记住Foo
模块不知道主机应用程序如何查找foo.utils
。
因此没有标准的方法来提供原始文件路径或相关路径。
因此,如果你在相对路径上写一些继电器的模块,那么这个模块
在某些环境中可能无法正常工作。
所以我建议使用完整名称空间,例如require 'foo.utils'
而不是require 'utils'