如何构建所有懒惰的Moose功能?

时间:2010-11-19 14:00:12

标签: perl moose

我在Moose对象中有一堆懒惰的功能。

有些建筑商需要一些时间才能完成。

我想nvoke所有构建器(转储“bomplete”对象)。 我可以一次性构建所有延迟功能,还是必须手动调用每个功能以使其运行?

3 个答案:

答案 0 :(得分:6)

如果你想在构建器中使用“lazy”属性,但确保在new返回之前构造它们的值,通常要做的是在BUILD中调用访问器。

sub BUILD {
    my ($self) = @_;

    $self->foo;
    $self->bar;
}

足以完成工作,但最好添加一条评论,并将这些显然无用的代码解释给不懂成语的人。

答案 1 :(得分:3)

也许您可以使用元类来获取“懒惰”属性的列表。例如:

package Test;

use Moose;


has ['attr1', 'attr2'] => ( is => 'rw', lazy_build => 1);
has ['attr3', 'attr4'] => ( is => 'rw',);

sub BUILD {
    my $self = shift;


    my $meta = $self->meta;

         foreach my $attribute_name ( sort $meta->get_attribute_list ) {

         my $attribute =  $meta->get_attribute($attribute_name);

        if ( $attribute->has_builder ) {
            my $code = $self->can($attribute_name);
            $self->$code;

        }
    }

}


    sub _build_attr1 { 1 }
    sub _build_attr2 { 1 }

答案 2 :(得分:2)

过去我曾多次提出这个要求,今天我实际上必须从元类中做到这一点,这意味着不允许进行BUILD调整。无论如何,我觉得分享会很好,因为它基本上完全与以下提到的一致:

  

'它会允许标记属性“这是懒惰的,因为它取决于   关于要构建的其他属性值,但我希望它被戳   施工结束前。“'

然而,derp derp我不知道如何制作CPAN模块,所以这里有一些代码: https://gist.github.com/TiMBuS/5787018

将上述内容放入Late.pm然后你可以这样使用它:

package Thing;
use Moose;
use Late;

has 'foo' => (
    is      => 'ro',
    default => sub {print "setting foo to 10\n"; 10},
);

has 'bar' => (
    is      => 'ro',
    default => sub {print 'late bar being set to ', $_[0]->foo*2, "\n"; $_[0]->foo*2},
    late    => 1,
);

#If you want..
__PACKAGE__->meta->make_immutable;
1;


package main;

Thing->new();
#`bar` will be initialized to 20 right now, and always after `foo`.
#You can even set `foo` to 'lazy' or 'late' and it will still work.