Module Lua:制作模块系统

Module Lua:制作模块系统,module,include,lua,Module,Include,Lua,我想创建一个程序,将有几个模块在不同的文件夹。主程序将确定需要加载的模块,并将加载该模块。此外,它还将加载一些核心功能 我创建了这个逻辑的原型,效果很好。 但由于我是新来的,我不确定什么是正确的方法来实现这一点 现在我有下一个文件结构: aoc(主程序): 核心/核心(核心功能加载程序): 核心/移动: local function move(direction, refuel, dig, attack) -- some logic in local function (to not be

我想创建一个程序,将有几个模块在不同的文件夹。主程序将确定需要加载的模块,并将加载该模块。此外,它还将加载一些核心功能

我创建了这个逻辑的原型,效果很好。 但由于我是新来的,我不确定什么是正确的方法来实现这一点

现在我有下一个文件结构:

aoc(主程序):

核心/核心(核心功能加载程序):

核心/移动

local function move(direction, refuel, dig, attack)
  -- some logic in local function (to not be overwriten in module)
end

function aoc.move()
  -- global function (it logic can be changed by module in case it needed)
  return move()
end
模块/mine/module(模块):

现在

lua>aoc矿山

lua>路径/to/aoc矿山

工作正常。但如果我做错了什么,有人能指点我吗


编辑:通过获取
aoc\u基本路径更改了逻辑

这不是一个答案,但我想要格式良好的代码。:-)
您可以稍微简化aoc:

aoc = {}
aoc_base_path = debug.getinfo(1).source:match("@(.*/)") or ''

dofile(aoc_base_path.."core/core")

local module = assert(loadfile(aoc_base_path.."modules/".. ... .."/module"))
module({select(2,...)},aoc) 

只需将Lua的库内置模块功能用于。通过适当的设置,您可以配置此标准系统,以便从任何位置以任何方式加载模块。具体目录,直接来自HTTP,由鸽子根据RFC 1149提供-它可以做到这一切。

要保持目录结构大致相同,但利用lua包系统,您可以使用以下方法:

在基本路径中有一个文件
aoc.lua

local aoc = {}

local module = ...
local dir = module:gsub("%.","%/"):sub(1,-4)

package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path

return aoc
在/core中有一个文件
init.lua
,该文件
需要包含的核心包

require"core.move"
然后,您的核心包将类似于:

local function move(direction, refuel, dig, attack)
  -- some logic in local function (to not be overwriten in module)
end

require"aoc".move = move
在/modules中,通过为每个模块提供一个lua文件,您可以使事情变得更简单,因此/modules/mine.lua看起来像:

local aoc = require"aoc"

aoc.move()
然后在lua提示下,您会写:

lua>需要“路径到.aoc”

lua>需要“核心”--加载核心模块

lua>需要“地雷”--装载地雷

编辑 如果希望保持相同的样式,请将aoc.lua更改为just
return{}
,并添加一个文件aoc,如下所示:

local dir = debug.getinfo(1).source:match("@(.*)/.*$") -- base path to my program
if not dir then dir = ''
else dir = dir..'/'
end

package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path

require"core"
for _,mod in ipairs{...} do
    require(mod)
end

我认为这种方法的优点是,所有的损坏都在一个文件中,在本例中是aoc,文件结构的其余部分使用相当标准的lua包约定。

您可能还需要稍微修改一下包路径。如果您是指带有
debug.getinfo(1)的行,那么这种方法可能会更好。@BartekBanachewicz。来源:match(@(.*/.$)
这只是一个示例。实际上,我以不同的方式得到了这个路径(我的程序是一些游戏的一个mod,它为我提供了
shell.getRunningProgram()
函数)。它是一个打字错误:
匹配(@(.*)/.$”
?可能提到了“
match”^(.*)/”
?它也可以写成
match'(.*)/'
@EgorSkriptunoff nope:
echo'print(debug.getinfo(1.source))>test;lua测试提供了
@test
@ArthurHalma-感谢您提供的信息。以前从未使用过此功能。谢谢,但您能解释一下这里的三个点是什么吗
“modules/”。。“/module”
mean(我玩Lua的时间不到24小时)?我认为当aoc获得超过1个参数时,这将是一个错误。@ArthurHalma-如果在另一个表达式中使用了vararg表达式,那么它将被调整为一个元素。我还编辑了我的问题。我改变了获取aoc基本路径的逻辑。现在我可以运行
aoc-mine
path/to/aoc-mine
@ArthurHalma-更改了我的答案。很好!如果将来没有关于文件组织结构的答案,我会接受它。这种方法有什么好处?它是标准的、内置的和可扩展的。你还需要什么?看起来这正是我需要的;)。我的文件结构如何?我可以保持现在的样子吗?@ArthurHalma,绝对可以。默认情况下,模块名称中的点将转换为文件系统中的子目录。将不再有机会以
path/to/aoc-mine
的形式执行我的程序了?看起来我无法访问
软件包
。因为我为一个游戏做了一个插件,所以我有一个有限的lua。那么您的代码
package.path=dir..”?.lua;“.package.path
return
attemp to index?(零值)
错误。
local function move(direction, refuel, dig, attack)
  -- some logic in local function (to not be overwriten in module)
end

require"aoc".move = move
local aoc = require"aoc"

aoc.move()
local dir = debug.getinfo(1).source:match("@(.*)/.*$") -- base path to my program
if not dir then dir = ''
else dir = dir..'/'
end

package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path

require"core"
for _,mod in ipairs{...} do
    require(mod)
end