2011-10-14 34 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結果:通過/ home/friedo/perl5的/

UR達姆的lib/perl5的/ x86_64的Linux的GNU的線程多/等級/ MOP/Method.pm線125

Carp.pm應該注意所謂@CARP_NOT知道哪個包到包變量避免,但它似乎只注意列表中的一個項目。例如,如果我加入這個我Test.pm

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

那麼結果是:

UR通過/ home/friedo/perl5的/達姆的lib/perl5的/ x86_64的Linux的GNU的線程多/Moose/Object.pm line 59

所以我應該只加到數組中,對吧?

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

ü在/home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm線R達姆59

麋:對象似乎未受影響。

我一直對此感到頭痛,現在似乎無法弄清楚發生了什麼。

謝謝。

回答

6

make_immutable似乎解決了這個問題。當然,如果你確實需要你的課程是可變的,我不知道該怎麼做。

沒有make_immutableTest->new調用Moose::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,如添加屬性。實際上,這不會成爲問題,因爲在第一次加載課程之後,你很少需要這樣做。

…

我們強烈建議您讓您的類不可變。它使您的代碼更快,編譯時間更少。這在創建許多對象時尤其明顯。

+0

啊,我還沒有考慮過。在完成課堂充實之後,我總是把' - > make_immutable'作爲事後的想法。 – friedo

+0

@friedo,通過承諾在當前運行期間不再更改類*,Moose會爲您的類創建一個有效的構造函數。它並不妨礙你改變模塊。 – ikegami

+0

我知道 - 我應該將它添加到我的包裝樣板中,而不是在完成時嘗試記住添加它。 – friedo