1

我有一个属性特征,我想在其他类属性的基础上进行设置。我真的想要一个属性特征的默认值,它获取类的副本,$self而不是属性的元数据。我想在我的课堂上做这样的事情:

after 'BUILD' => sub {                                                     
  my $self = shift;                                                        
  $self->meta->get_attribute('id')->column_name( $self->_unique_key_name );
};  

但是,我想保持我的属性特质RO?这可能吗。我知道 MOP 允许设置类属性的值,但我不知道如何在元属性上设置属性。

4

1 回答 1

1

这听起来像是一个非常奇怪的设计(为什么元类需要它所描述的类的实例?)——但是您可以通过使用元类的元类来轻松地做到这一点(请记住,Moose 元类是使用 MOP 引导的本身):

$self->meta->meta->get_attribute("foo")->default($some_value);

还要记住,如果它们本身是引用,则需要将默认值包装在 coderef 中:$some_value = sub { $instance };


实际上,这不起作用 - 'default' 是只读的。与其在如此低的级别上摆弄 MOP,我会敦促您重新考虑您的设计 - 例如将您的“默认”存储在另一个属性中,并编写一个委托给它的默认子:

package MyApp::Meta::Attribute::Trait::Foo;

# set at runtime, when we have an instance to store here
has _default_of_foo => (
    is => 'rw', isa => 'Object',
);
has foo => (
    is => 'ro', isa => 'Object',
    lazy => 1,
    default => sub { shift->_default_of_foo },
);
于 2010-11-16T16:55:21.507 回答