5

我对MooseX::DeclareBUILD中的方法有困难。如果我说:

#!/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;

一切正常(但丑陋且与其余代码格格不入)。

4

3 回答 3

6

BUILD 需要一个 arg,如果您不需要它,只需说:

method BUILD($) { ... }
于 2009-07-21T09:27:04.317 回答
5

它失败了,因为BUILD需要一个单参数方法签名。默认情况下,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 作为参数。

于 2009-07-21T03:24:48.277 回答
-2

Perl 理解sub并因此进入当前包的符号表。&Foo::BUILD,在Devel::Declare和其他魔术从类闭包中创建了一个包范围之后。

Moose专门寻找BUILDsub 以允许您操作构造函数逻辑。我的猜测(虽然我没有一直追踪它)是 MooseX 模块不会妨碍 Moose 试图做的事情。这样一个本地人BUILD就永远被传递给 Moose 魔法来确定构造函数的逻辑。

另一方面,method关键字更多是Devel::Declare在元类结构中创建方法的魔法。

于 2009-07-20T21:47:48.623 回答