2009-07-20 100 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($) { ... } 
相关问题