2009-07-20 89 views
5

我在MooseX::DeclareBUILD方法中遇到困難。如果我說:在MooseX :: Declare中創建BUILD方法的正確方法是什麼?

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

我得到以下比有用的錯誤信息少:

Reference found where even-sized list expected at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 335. 
Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types::Structured::Tuple[Object],MooseX::Types::Structured::Dict[]]' failed with value [ [ Foo=HASH(0x804b20) ], { HASH(0x8049e0) => undef } ], Internal Validation Error is: Validation failed for 'MooseX::Types::Structured::Dict[]' failed with value { HASH(0x8049e0) => undef } at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 365 
     MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0xb8aab0)', 'ARRAY(0xb8ab30)') called at /Users/cowens/perl5/lib/perl5/MooseX/Method/Signatures/Meta/Method.pm line 139 
     Foo::BUILD('Foo=HASH(0x804b20)', 'HASH(0x8049e0)') called at generated method (unknown origin) line 25 
     Foo::new('Foo') called at test.pl line 13 

但如果我說:

#!/usr/bin/perl 

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    sub BUILD { 
     my $self = shift; 
     print "I was called\n"; 
    } 
} 

Foo->new; 

一切工作得很好(但是是醜陋和出與其他代碼的地方)。

回答

-2

Perl可以理解sub,因此可以進入當前包的符號表。 & Foo :: BUILD,之後Devel::Declare等魔術已經從封閉類創建了一個封裝範圍。

Moose特別尋找BUILD sub允許您操作構造函數邏輯。我的猜測(儘管我還沒有完全追蹤)是MooseX模塊不能實現Moose正在嘗試做的事情。所以一個本地的BUILD永遠傳遞給穆斯的魔法來確定構造邏輯。

另一方面,method關鍵字更具有魔法,可以在元類結構中創建方法。

5

由於BUILD需要一個arg方法簽名,因此失敗。默認情況下,MooseX::Declare會創建一個與BUILD被調用的方式不兼容的簽名。 (細節對我來說很模糊。)我知道,因爲我遇到過類似的錯誤。我當然同意錯誤信息可能會更有啓發性;對於很多Moose來說這是真的。

不管怎樣,我知道了這樣的工作:

use MooseX::Declare; 

class Foo { 
    has foo => (is => "rw", isa => "Str", default => "foo"); 

    method BUILD(Item $href) { 
     print "I was called\n"; 
    } 
} 

Foo->new; 

希望有所幫助。

您可以擺弄簽名並嘗試更具體的類型;我認爲Moose發送了一個尚未失敗的對象的hashref作爲參數。

+0

哇,這是醜陋的,`$ self`存在並保持祝福的對象,但你也有這個沒用hashref充滿了傳遞給`new`的參數。這是另一個美麗系統的重大瑕疵。 – 2009-07-21 05:04:39

6

BUILD需要的阿根廷,如果你不需要它,只是說:

method BUILD($) { ... } 
相關問題