繁体   English   中英

“compose_attributes”显然是在属性组合之前调用的

[英]"compose_attributes" is apparently called before attributes are composed

这是做这件事的另一种尝试,本质上是创建一个冻结的 class:

my class MetamodelX::Frozen is Metamodel::ClassHOW {

    method compose_attributes(Mu \type) {
        for self.attributes(type, :local ) -> $a {
            my $attr = Attribute.new( :0rw, :0has_accessor, :name( $a.name ),
             :type($a.type), :package($a.package));
            self.add_attribute(type, $attr );
        }
        callsame();
    }
}

my package EXPORTHOW {
    package DECLARE {
        constant frozen = MetamodelX::Frozen;
    }
}

与@jnthwrthngtn answer here类似,其中方法以特定形状创建以防止 Class 如何以通常的方式创建它们,我在这里所做的是以只读方式重新创建属性并且没有访问器,使用rest的强制属性相同。 但是,当您尝试实例化它时,这会失败:

Package 'Foo' already has an attribute named '$!bar'

在任何罕见的情况下,这只会消除访问器,因为该属性已经是只读的,并且无法制作真正的冻结 class (此外,它仍然可以增强,因此不会被长期冻结)。 你能想到什么其他方法来达到同样的效果吗?

属性组成不是class添加属性的时候; 相反,它是以下时间:

  • 我们承诺 class 的一组特定属性,并将其传达给底层运行时(通常是 MoarVM),它计算 object 的 memory 布局
  • 我们告诉每个Attribute object 组成自己,这是它生成访问器、 handles相关方法等的触发器

我不清楚您打算实现什么,因为无论如何默认情况下属性在外部都是只读的,因此如果有人在声明为frozen的东西上定义了一个rw ,那么产生错误可能会更有意义。 如果您确实想修改属性,您可能会更幸运地覆盖add_attribute并调整该属性的工作方式(例如, method add_attribute($obj, $attr) { callwith($obj, $attr.clone(:,rw: :!has_accessor)) }可以实现你想要的)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM