2010-11-19 2 views
6

나는 무스 오브젝트에 많은 게으른 피처가있다.모든 게으른 무스 기능을 어떻게 만들 수 있습니까?

일부 빌더는 완료하는 데 약간의 시간이 필요합니다.

모든 빌더를 nvoke하고 싶습니다 (덤프 "bomplete"오브젝트). 모든 게으른 기능을 한꺼번에 만들 수 있습니까? 아니면 빌더가 실행되도록 수동으로 각 기능을 호출해야합니까?

+1

당신은'default'를 사용해서는 안되나요? 나는'lazy'의 요점은 처음 사용할 때까지 속성 값을 만드는 것을 연기하는 것이라고 생각했습니다. 객체 생성시 모든 속성을 설정해야한다면'default'가 더 유용 할 것입니다. 또는, 독자적인'BUILD' 메소드를 제공 할 수 있습니다. –

+0

이것은 합리적으로 공통적 인 관용어이며 이에 대한 적절한 이유가 있습니다. – hobbs

+0

기본적으로'BUILD'에서 모든 작업을 수행 할 수 있지만 속성마다 메소드를 갖는 것이 더 좋습니다. 값을 계산하기 위해 속성마다 메소드를 사용하려는 경우 빌더가 될 수 있습니다. 그러나 빌더가 다른 속성에 액세스하려고하면 빌트인 속성을 초기화해야만 게으려 야합니다. 그리고 "lazy하지만 단지 * little bit * lazy"속성 옵션은 없습니다 :) – hobbs

답변

6

빌더에 "게으른"속성을 갖고 싶지만 new이 반환되기 전에 값이 생성되도록하려면 일반적으로 할 일은 BUILD의 접근자를 호출하는 것입니다.

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

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

이 작업을 완수하기에 충분하지만, 그것은뿐만 아니라 관용구를 모르는 사람이 분명히 쓸모없는 코드를 설명하는 주석을 추가하는 아마 가장 좋습니다.

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

, 오늘 나는 실제로 사용할 수없는 빌드 조정이 의미가없는 메타 클래스에서 그것을 할 수 있었다. 어쨌든 나는 기본적으로 에테르 언급 정확히 않기 때문에 공유하는 것이 좋을 것입니다 느낌 :

'가 건설 될 다른 속성 값에 을 달려 있기 때문에,이 게으른 "특성을 표시 할 수 것이지만, 내가 원하는 .이 공사가 완료되기 전에 찌르고 할 " '

그러나, 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. 
관련 문제