Lua:制作模块系统

时间:2013-04-12 07:28:23

标签: module include lua

我想创建一个程序,它将在不同的文件夹中包含多个模块。主程序将确定需要加载哪个模块并将加载它。除此之外,它还将加载一些核心功能。

我创建了这个逻辑的原型并且运行良好。 但由于我是Lua的新手,我不确定采用这种方法的正确方法。

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

enter image description here

aoc (主程序):

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

local aoc_base_arg={...}
dofile(aoc_base_path.."core/core")

local module = assert(loadfile(aoc_base_path.."modules/"..aoc_base_arg[1].."/module"))
local arg = table.copy(aoc_base_arg) -- this is my custom function (I'm not provide you with listing, it just copy one table to another one
table.remove(arg,1)
module(arg,aoc) -- pass to module all arguments except first one

核心/核心(核心功能加载器):

dofile (aoc_base_path..'core/move')

芯/移动

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

modules / mine / module (模块):

local arg={...} -- I passed 2 arguments in aoc main program
arg = arg[1]
local aoc = arg[2]
aoc.move()

现在

  

lua> aoc mine

  

lua> 路径/ to / aoc mine

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

编辑:改变了获取aoc_base_path

的逻辑

3 个答案:

答案 0 :(得分:1)

这不是答案,但我想要很好地格式化代码。 :-)
您可以简化 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) 

答案 1 :(得分:0)

只需使用Lua的库内置模块功能require。通过正确设置package.loaders,您可以将此标准系统配置为从您想要的任何地方以任何方式加载模块。直接来自HTTP的特定目录,由鸽子根据RFC 1149提供 - 它可以做到这一切。

答案 2 :(得分:0)

为了保持您的目录结构大致相同,但是使用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.luarequire是您要包含的核心包

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>需要 “path.to.aoc”

LUA>要求“核心” - 加载核心模块

LUA>要求“我的” - 加载我的

修改

如果您想要保持相同的样式,请将aoc.lua更改为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包约定。