Class 支持";“递归对象”;在卢阿

Class 支持";“递归对象”;在卢阿,class,lua,Class,Lua,我是lua的新手,在课堂作业中遇到以下问题: 我们目前扩展lua以支持对象和继承。其语法是 Class{'MyClass', attribute1 = String, attribute2 = Number } Class{'MySubClass', MyClass, attribute3 = Number } 这个很好用。真正的问题在于下一个任务:我们应该支持“递归类型”,这意味着类似于 Class{'MyClass', attribute = MyClass}

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

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

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

Class{'MySubClass', MyClass,
    attribute3 = Number
}
这个很好用。真正的问题在于下一个任务:我们应该支持“递归类型”,这意味着类似于

Class{'MyClass', attribute = MyClass}
应生成一个与类具有相同类型字段的类。当调用此“类构造函数”时,变量
MyClass
nil
,这就是参数表没有条目
属性的原因。如何访问此属性

我的第一个想法是使用某种
nil
-表,每当使用未设置的键调用全局
\uu索引时都会返回该表。此
nil
-表的行为应类似于正常的
nil
,但可以在“类构造函数”中进行检查。这种方法的问题是比较,比如
nil==unknown
。这应该返回
true
,但是由于
nil
表的
\uu eq
元方法从未被调用,我们无法返回
true

有没有其他我目前忽略的方法?任何暗示都将不胜感激

提前谢谢

编辑: 这里是“测试文件”的相关部分。在类中对代码进行评级的测试是另一个测试,稍后发布

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
只是全局表(
\u G
)中的一个查找,您可能会弄乱它的元表的
\u索引
,以返回一个新定义的MyClass对象(稍后需要用详细信息填充)

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

  • 非常不安全,因为您可能会得到一个未定义的类(或者更糟的是,您可能会无意中创建一个无限查找循环。相信我,我已经去过了)
  • 调试非常困难,因为对不存在的变量的每个
    \u G
    查找现在都将返回一个新创建的类对象,而不是nil(通过要求类名以大写字符开头,可以在一定程度上减少此问题)

如果您使用这种方法,请确保同时覆盖
\uuu newindex

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

Class{'MyClass', attribute = 'MyClass'}
类的实现中检测字符串
,并在创建类后使用
\u G[string]
对其进行处理

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

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

是应该支持这个调用,还是有其他语法(隐式或显式)。因为如果没有你所指的那种黑客(这是可能的,但丑陋和昂贵),我不知道这怎么可能。不幸的是,它必须是这种语法。我有一个“testfile”,它不应该被更改,并且需要给定的语法。任务的这一部分(第一部分是实现继承)也被标记为非常困难。这就是为什么我认为一定有某种黑客参与。另一个(可怕的)选项-如果您得到
nil
,请使用
debug.backtrace
获取当前源位置,并以文本形式读入源文件,以查找变量查找的内容。主要问题是,在像
{'MyClass',attribute=MyClass}
这样构造表时,正在对'rvalues'进行完全计算。如果发生这种情况时没有定义
MyClass
,那么
Class
看到的只是
{'MyClass',attribute=nil}
,这与
{'MyClass'}
是无法区分的。如果允许您将语法改为类似的内容
Class'MyClass'{attribute=MyClass}
这将简化实现。如果我正确理解这一点,这将无法解决
nil==unknown
的问题,或者会吗?但我喜欢大写惯例的想法。这可能对我的导师的检查有用。我不知道这种“递归类型”在支持所有
nil
检查时应该如何工作。我很好奇他们的解决方案是什么。谢谢不,这种方法不会修复
nil==unknown
——也不应该。无论何时从
获取
MyClass
,都会创建一个占位符。在创建类时,首先检查占位符是否已经存在并填充它,否则直接创建类对象。