class – 如何使用元对象协议向对象添加属性?

前端之家收集整理的这篇文章主要介绍了class – 如何使用元对象协议向对象添加属性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图回答 this问题,并认为我可以使用元对象协议向类添加属性.这是一个最小的例子,我尝试在构造后向类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,对于类,属性是每个类型,而不是每个对象;代码结构表明,期望可能是每个对象.没有任何东西可以让原型面向对象变得不可能(实际上MOP的设计是为了有人可以在Perl 6中实现这样的对象系统),但Perl 6本身并没有指定提供这一点.

因此,利用所提供的对象系统,这种操作需要在编译时和关闭之前完成.这可以通过以下方式实现:

class Configuration {
    BEGIN {
        my $attr = Attribute.new(
            :name('$!test'),# Trying to add a "test" attribute
            :type(Str),:package(Configuration)
        );
        Configuration.^add_attribute( $attr );
    }
}

my $config = Configuration.new;
say "Current attributes: ",$config.^attributes();
$config.^attributes[0].set_value( $config,"Hello" );
say $config.test;

这是Perl 6动态的许多地方之一,主要是邀请程序员参与编译时,而不是在运行时使所有事情都成为可能.

最后,我将注意到有一种方法可以将属性添加到现有对象,并且基于每个对象:通过使用do将角色混合到其中.这可以通过改变对象的类型来实现. here上有一些文档.

猜你在找的Perl相关文章