在 lua 中支持 "recursive objects"

Supporting "recursive objects" in lua

我是 lua 的新手,在 class 的作业中遇到以下问题:

我们目前扩展 lua 以支持对象和继承。语法是

Class{'MyClass', 
    attribute1 = String,
    attribute2 = Number
}

Class{'MySubClass', MyClass,
    attribute3 = Number
}

这很好用。真正的问题在于下一个任务:我们应该支持 "recursive types",这意味着像

这样的调用
Class{'MyClass', attribute = MyClass}

应该导致 class 具有与 class 相同类型的字段。当这个 "class-constructor" 被调用时,变量 MyClassnil,这就是参数 table 没有条目 attribute 的原因。如何访问此属性?

我的第一个想法是使用某种 nil-table,每次使用未设置的键调用全局 __index 时,它都会被 returned。 nil-table 应该像正常的 nil 一样运行,但可以在 "class-constructor" 中检查。这种方法的问题是像 nil == unknown 这样的比较。这应该 return true,但是由于从未调用 nil-table 的 __eq 元方法,我们不能 return true.

有没有我目前忽略的另一种方法?非常感谢任何提示。

提前致谢。

编辑: 这里的相关部分是"testfile"。在 class 中对代码进行评级的测试是另一个测试,稍后发布。

three = 3
print( three  == 3 , "Should be true")
print( unknown == nil , "Should be true" )

Class{'AClass', name = String, ref = AClass}
function AClass:write()
    print("AClass:write(), name of AClass:", self.name)
end

aclass = AClass:create("A. Class")
aclass:write()

因为 MyClass 只是在全局 table (_G) 中查找,你 可能 弄乱它的元 table 的 __index 到 return 新定义的 MyClass 对象(您稍后需要填写详细信息)。

然而,虽然可行,但这样的实施是

  • 非常不安全,因为您最终可能会得到一个未定义的 class(或者更糟的是,您最终可能会无意中创建一个无限查找循环。相信我,我去过那里)
  • 很难调试,因为每个 _G 查找不存在的变量现在都会 return 一个新创建的 class 对象而不是 nil(这个问题可以稍微减少通过要求 class 名称以大写字符开头)

如果你走那条路,一定要覆盖 __newindex

如何以字符串形式提供参数?

Class{'MyClass', attribute = 'MyClass'}

检测 Class 实现中的字符串并在 _G[string] 之后 处理它们创建 class

或者,使用函数延迟查找:

Class{'MyClass', attribute = function() return MyClass end}