【问题标题】:Lua 5.2 metatables and environmentLua 5.2 元表和环境
【发布时间】:2015-04-15 05:42:22
【问题描述】:

我有这样的结构:

context = {
  pi = math.pi,
  sin = math.sin,
  cos = math.cos,
  tan = math.tan,
  print = print
}

modules = {
  m1 = {
    variables = { x = 1 },
    update = function(self)
      local _ENV = self.variables
      x = 2
      m2.x = 2
    end
  },
  m2 = {
    variables = { x = 1 },
    update = function(self)
      local _ENV = self.variables
    end
  }
}

setmetatable(modules.m1, {__index = modules.m1.variables})
setmetatable(modules.m1.variables, {__index = context})

setmetatable(modules.m2, {__index = modules.m2.variables})
setmetatable(modules.m2.variables, {__index = context})

setmetatable(context, {__index = modules})

这个想法是用户在 UI 中输入代码,然后将代码粘贴到不同模块的 update 函数中,就在设置 local _ENV 的位置之后。这个用户输入的代码应该被沙盒化。它应该能够访问一些功能(context 表中的功能)和其他模块的内容。 m1:update 中的代码应该能够引用 m1.variables 中的变量而无需限定它们;其他模块中的变量(即m2.variables 中的变量)应该可以通过使用模块名称(即m2.x)限定它们来访问。

但是我得到的结果是这样的:

$ lua -i test.lua
> = modules.m1.x
1
> = modules.m1.variables.x
1
> = modules.m2.x
1
> = modules.m2.variables.x
1
> = modules.m1:update()
> = modules.m1.x
2
> = modules.m1.variables.x
2
> = modules.m2.x
2
> = modules.m2.variables.x
1

为什么modules.m2.variables.x 没有更新?如果看起来modules.m2.xmodules.m2.variables.x 不同,那么modules.m2.x 来自哪里?

【问题讨论】:

    标签: lua lua-table lua-5.2


    【解决方案1】:

    modules.m2.variables.x 没有更新,因为您只设置了__index metamethod(在检索不存在的键时使用),而不是__newindex metamethod(在为不存在的键分配值时使用) ,因此该值存储在 modules.m2.x 表中,而不是您想要的 modules.m2.variables.x 表中。

    如果我像setmetatable(modules.m2, {__index = modules.m2.variables, __newindex = modules.m2.variables}) 一样添加__newindex,我会得到预期的结果。

    【讨论】:

      猜你喜欢
      • 2014-01-11
      • 2012-11-04
      • 1970-01-01
      • 2013-04-06
      • 2012-04-02
      • 2012-08-12
      • 1970-01-01
      • 2015-04-14
      • 2012-06-16
      相关资源
      最近更新 更多