如何动态添加 class 属性?

How to add a class attribute dynamically?

如何向 class 动态添加属性?我试过了,但它抱怨缺少方法,我不确定为什么,因为我没有尝试添加方法。

use v6.d;

class Foo does Metamodel::AttributeContainer {
    submethod BUILD(:$attr) {
        my $a = Attribute.new(:name($attr), :type(Str), :package(Foo));
        self.add_attribute(self, $a);
    }
}

my Foo $foo = Foo.new(:attr('bar'));
$foo.bar = 'baz';  # No such method 'bar' for invocant of type 'Foo'
say $foo.bar;

一旦 class 被组合,就无法将其添加到 class 中——也就是说,在其结束卷曲 } 被解析之后。一般来说,使用元模型完成的声明性事情需要在编译时完成。

关于您在问题中编写的代码:

  • 从概念上讲,属性存在于每个 class,而不是每个对象,因此无法实现这样的功能。
  • 即使把它放在一边,扮演 Metamodel::AttributeContainer 的角色在这里也无济于事;它将被组合成一个元class,它包含关于属性的元数据,而不是class,它具有正在声明的属性。
  • 未找到方法 bar 的错误是因为属性访问器 - 即使是生成的 - 只是一个普通方法。

如果不首先了解您试图解决的问题,就很难知道该建议什么。不管是什么,都不能通过尝试为每个对象添加属性来解决。或许可以考虑:

  • 使用 mixin,这是一种更改单个对象的方法
  • 有一个 class 包含用于存储其数据的散列,然后使用 FALLBACK 方法将方法调用解析为对有效键的散列访问