Как я могу сделать так, чтобы все ленивые функции Moose создавались? - PullRequest
6 голосов
/ 19 ноября 2010

У меня есть куча ленивых функций в объекте Moose.

Некоторым строителям требуется некоторое время, чтобы закончить.

Я бы хотел вызвать всех строителей (сбросить объект "bomplete"). Могу ли я сделать так, чтобы все ленивые функции создавались одновременно или я должен вызывать каждую функцию вручную, чтобы запустить ее сборщик?

Ответы [ 3 ]

6 голосов
/ 19 ноября 2010

Если вы хотите иметь «ленивые» атрибуты со сборщиками, но убедитесь, что их значения создаются до возврата new, обычно нужно вызвать методы доступа в BUILD.

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

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

достаточно, чтобы выполнить работу, но, вероятно, лучше добавить комментарий с объяснением этого, по-видимому, бесполезного кода тому, кто не знает идиомы.

3 голосов
/ 20 ноября 2010

Может быть, вы могли бы использовать мета-класс, чтобы получить список «ленивых» атрибутов. Например:

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 голосов
/ 12 июня 2013

В прошлом у меня было такое точное требование несколько раз, и сегодня я фактически должен был выполнить его из метакласса, что означало, что настройка BUILD не допускается. Во всяком случае, я чувствовал, что было бы хорошо поделиться, поскольку он в основном делает именно то, что упоминал эфир:

«Это позволило бы помечать атрибуты», это лениво, потому что это зависит на других значениях атрибута, которые будут построены, но я хочу, чтобы он ткнул до завершения строительства. "'

Однако, сумасшедший сумасшедший, я понятия не имею, как сделать модуль 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.
...