2011-10-14 3 views
4

BUILD 메서드가 실패하면 클래스를 폭파 시키길 원합니다. 그러나 croak을 사용하여 오류를 처리하면 오류는 발신자의 코드가 아닌 Class/MOP/Method.pm에서보고됩니다. (즉, 개체를 인스턴스화하는 호출자입니다.) IOW, croak은 호출 트리를 충분히 멀리 짖지 않습니다.무스 BUILD 메서드에서 울기

보라 :

package Test; 

use Moose; 
use Carp 'croak'; 

sub BUILD { 
    croak 'u r dum'; 
} 

1; 

가에 Test 결과를 인스턴스화 : lib에는 집/friedo/perl5가//에

UR 둠/perl5의/x86_64에-리눅스 GNU 스레드 멀티/클래스/MOP/Method.pm 라인 (125)

Carp.pm은 할 패키지를 알고 @CARP_NOT라는 패키지 변수에주의를 지불하도록되어 피하십시오. 그러나 목록의 한 항목에만주의를 기울이는 것으로 보입니다. 예를 들어, 내 Test.pm이를 추가하는 경우 :

our @CARP_NOT = ('Class::MOP::Method'); 

그런 다음 결과는 다음과 같습니다

/perl5의/x86_64에-리눅스 GNU 스레드 멀티 lib 디렉토리 홈/friedo/perl5가//에서 UR 둠 /Mose/Object.pm 줄 59

그래서 배열에도 추가해야합니다. 맞습니까?

our @CARP_NOT = ('Class::MOP::Method', 'Moose::Object' ); 

유는 59

무스 :: Object가 영향을받지 않는 것으로 보인다 /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm 라인에 둠 r에.

나는 잠시 동안 내 머리를 쾅쾅 대고 있었고, 무엇이 엉망인지 알아낼 수 없었다.

감사합니다.

답변

6

make_immutable이 수정되는 것으로 보입니다. 물론, 클래스를 변경해야하는 경우 어떻게해야할지 모르겠다.

make_immutable이없는 경우 Test->newMoose::Object->new을 호출합니다. 당신이 confess 출력을 보면, 당신은 알게 될 것이다 :

 Test::BUILD(...) called ... 
    Class::MOP::Method::execute(...) called ... 
    Moose::Object::BUILDALL(...) called ... 
    Moose::Meta::Class::new_object(...) called ... 
    Moose::Object::new('Test') called at ./t.pl line 17 
#!/usr/bin/env perl 

package Test; 

use Moose; 
use namespace::autoclean; 

use Carp 'croak'; 

sub BUILD { 
    croak 'u r dum'; 
} 

__PACKAGE__->meta->make_immutable; 

package main; 

my $t = Test->new; 

출력 :

[[email protected] tmp]$ ./t.pl 
u r dum at constructor Test::new (defined at ./t.pl line 14) line 28

Moose::Cookbook::Basics::Recipe7에서 :

둘째, 당신은 더 이상를 통해 변경할 수 있습니다 속성 추가와 같은 메타 클래스 API 실제로 클래스를 처음로드 한 후이를 수행 할 필요가 거의 없기 때문에 이것은 문제가되지 않습니다.

& hellip;

클래스를 변경하지 않는 것이 좋습니다. 작은 컴파일 타임 비용으로 코드를 훨씬 빠르게 만듭니다.이것은 많은 객체를 생성 할 때 특히 두드러 질 것입니다.

+0

아, 그런 생각조차하지 않았습니다. 클래스를 완성한 후에는 항상 make_immutable을 사용합니다. – friedo

+0

@friedo, 현재 실행 중에 * 더 이상 클래스를 변경하지 않기로 약속함으로써 Moose는 클래스에 효율적인 생성자를 만듭니다. 그것은 당신이 모듈을 바꾸는 것을 방해하지 않습니다. – ikegami

+0

알아요 - 제가 다 끝나면 그것을 추가하는 것을 기억하는 대신 내 패키지 보일러 플레이트에 추가해야합니다. – friedo