Lua - 模块内部的变量命名空间

时间:2013-01-21 09:52:27

标签: inheritance lua

我使用此变量创建了一个名为BaseModule的变量template_path和函数get_template的模块:

module("BaseModule", package.seeall)
template_path = '/BASEMODULE_PATH/file.tmpl'
function get_template()
  print template_path
end

然后我创建另一个名为“ChildModule”的模块

local BaseModule = require "BaseModule"
module("ChildModule", package.seeall)
setmetatable(ChildModule, {__index = BaseModule})
template_path = '/CHILDMODULE_PATH/file.tmpl'
some_child_specific_variable = 1

执行setmetatable我想将所有变量和函数从BaseModule复制到ChildModule(假设继承它们)并添加一些额外的方法和变量到新模块。

问题在于我打电话

ChildModule.get_template

我希望它返回 /CHILDMODULE_PATH/file.tmpl ,但不会。它会返回 /BASEMODULE_PATH/file.tmpl

但是当我访问ChildModule.template_path时,它包含正确的值(来自ChildModule)。

如何让Lua在ChildModule方法中使用ChildModule.get_template变量但不使用BaseModule(父模块)变量? Lua中没有这个对象,那么如何告诉Lua使用当前值?

2 个答案:

答案 0 :(得分:3)

我认为您仍在使用已弃用的Lua版本。无论如何,您需要使用某个函数在template_path内设置BaseModule值,并将基数中的template_path设置为local。所以,像这样:

BaseModule

module("BaseModule", package.seeall)
local template_path = "/BASEMODULE_PATH/file.tmpl"
function get_template()
  print(template_path)
end
function set_template( sLine )
  template_path = sLine
end

ChildModule

local BaseModule = require "BaseModule"
module("ChildModule", package.seeall)
setmetatable(ChildModule, {__index = BaseModule})
ChildModule.set_template( "/CHILDMODULE_PATH/file.tmpl" )
some_child_specific_variable = 1
ChildModule.get_template()

由于您继承,不得尝试直接设置base-module的全局变量。

答案 1 :(得分:0)

我认为您正在尝试操作变量,而您可能想要操纵正在创建的对象的属性。也许是这样的:

-- base.lua
local M = {}
M.template_path = '/BASEMODULE_PATH/file.tmpl'
function M:get_template()
  return self.template_path
end
return M

-- child.lua
local M = {}
setmetatable(M, {__index = require "base"})
M.template_path = '/CHILDMODULE_PATH/file.tmpl'
M.some_child_specific_variable = 1
return M

-- main.lua
local base = require "base"
local child = require "child"

print(base:get_template(), child:get_template(),
  child.some_child_specific_variable)

这将打印:

/BASEMODULE_PATH/file.tmpl  /CHILDMODULE_PATH/file.tmpl 1

正如您所料。

顺便说一句,你可以将child.lua变成一行:

return setmetatable({template_path = '/CHILDMODULE_PATH/file.tmpl',
  some_child_specific_variable = 1}, {__index = require "base"})

不是你应该,但你可以。