Lua - 如何动态调用模块?

时间:2014-01-13 02:53:58

标签: oop module lua

这是我正在使用的一些非常简化的Lua代码。我需要知道如何动态调用另一个模块('zebra'):

avar = require "avar"
bvar = require "bvar"

function create(zebra)
  print(zebra.new())
end

print(create(avar))

以下是两个模块:

local Avar = {}

function Avar.new()
  return "avar"
end

return Avar

local Bvar = {}

function Bvar.new()
  return "new"
end

function Bvar.old()
  return "old"
end

return Bvar

如果我尝试将字符串“avar”传递给我的'create'函数,它就不起作用。如果我传入“avar”这个词没有引号,它确实有效,但是,我不明白什么是没有引号的avar?这似乎是一张空白的桌子?不知道如何在我的主程序中将空白表作为参数传递。

但也许我完全走错了路。如何动态调用模块?

3 个答案:

答案 0 :(得分:2)

没有引号的

avar是您创建的全局变量。它被初始化为require函数 1 返回的值,这是您正在调用的模块返回的值。在这种情况下,它是一个恰好是函数的new字段的表。

1 在Lua中导入模块是通过常规函数而不是特殊语法完成的。可以省略函数调用括号,因为如果使用单个参数编写函数调用并且该参数是字符串或表,则parens是可选的。

除此之外,还有其他一些令你困惑的事情:

  • 您在avar上存储的表格不是空的!您可以通过执行for k,v in pairs(avar) do print(k,v) end来打印其内容。

  • 默认情况下,avarbvarcreate变量是全局变量,其他模块会看到这些变量。大多数时候你宁愿把它们变成本地的。

    local avar = -- ...
    local bvar = -- ...
    
    local function create (zebra)
      -- ...
    end
    
  • create function显然需要一个表,因为它对其参数进行表索引(获取new键并调用它)。该字符串没有“新”键,因此无法使用。

  • 您并非真正动态调用模块。您需要以常规方式使用该模块,并且只是将模块返回值传递给函数。

  • create始终返回nil,因此print(create(avar))没有意义。您可能希望修改create以返回其对象而不是打印它。

答案 1 :(得分:1)

您可以随时要求:

function create(zebraModuleName)
  zebraType = require(zebraModuleName)
  print(zebraType .new())
end

print(create("avar"))
print(create("bvar"))

答案 2 :(得分:0)

您可以使用lua语言中的标准require或使用元表/元方法来构建自己的加载器。

1。创建全局函数:

function dynrequire (module)                                                                                           
  return setmetatable ({},{
    __index = function (table,key)
      return require(module..'.'..key)
    end
  })
end

2。创建对package.path可见的项目树

./MySwiss/
  \___ init.lua
  \___ cut.lua
  \___ glue.lua
  \___ dosomething.lua

3。使您的模块动态化 您只需要将此行放在MySwiss/init.lua上(就像您命名一个PHP类一样):

return dynrequire('MySwiss')

4。需要您的模块并动态使用子属性 在脚本上,您只需要MySwiss和文件夹文件(或带有dynrequire('MySwiss.SubFolderName')的子文件夹。

var X = require('MySwiss')
X.glue()

请注意,MySwiss没有粘合键。但是,当您尝试访问胶合键时,元方法__index会尝试需要子模块。您可以使用此技术构建完整的项目树。唯一的缺点是没有这样包装外部依赖项。