我试图回答this问题,并认为我可以使用元对象协议向类添加属性。这是一个我尝试添加属性的最小示例test
到班级Configuration
施工后:
use v6;
class Configuration {
}
my $config = Configuration.new;
my $attr = Attribute.new(
:name('$.test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
$config.^add_attribute( $attr );
$config.^compose();
say "Current attributes: ", join ', ', $config.^attributes();
$attr.set_value( $config, "Hello" ); # <-- This fails with no such attribute '$.test'
say $config.test;
当我运行这个时,我得到:
Current attributes: $.test
P6opaque: no such attribute '$.test' on type Configuration in a Configuration when trying to bind a value
in block <unit> at ./p.p6 line 16
属性不能在类组合时间之后添加,这发生在编译时关闭时}
编译程序时就达到了。 (这是针对以下情况的P6opaque
表示。存在允许这样做的表示并非不可能,但目前还没有指定。)
更进一步说,.^add_attribute
在元对象上调用,并且对于class
属性是按类型计算的,而不是按对象计算的;代码结构表明,期望可能是针对每个对象的。没有什么可以使原型面向对象变得不可能(实际上 MOP 的设计是为了让有人可以在 Perl 6 中实现这样的对象系统),但同样,Perl 6 本身没有指定任何内容来提供这一点。
因此,对于提供的对象系统,此类操作需要在编译时和关闭之前完成}
。可以通过以下方式实现:
class Configuration {
BEGIN {
my $attr = Attribute.new(
:name('$!test'), # Trying to add a "test" attribute
:type(Str),
:has_accessor(1),
:package(Configuration)
);
Configuration.^add_attribute( $attr );
}
}
my $config = Configuration.new;
say "Current attributes: ", join ', ', $config.^attributes();
$config.^attributes[0].set_value( $config, "Hello" );
say $config.test;
这是 Perl 6 动态的众多地方之一,主要是通过邀请程序员参与编译时,而不是通过在运行时使所有事情成为可能。
最后,我要指出的是,有一种方法可以在每个对象的基础上向现有对象添加属性:通过使用does
混合一个角色。这是通过改变对象的类型来实现的。有一些文档does
here.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)