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 は引数を取ります。必要ない場合は、次のように言ってください。

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

BUILD引数が 1 つのメソッド シグネチャが必要なため、失敗しています。デフォルトでは、呼び出し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 は、まだ祝福されていないオブジェクトのハッシュリファレンスをパラメーターとして送信していると思います。

于 2009-07-21T03:24:48.277 に答える
-2

Perl はsubそれを理解し、現在のパッケージのシンボル テーブルへのエントリが作成されます。&Foo::BUILD、Devel::Declareおよびその他の魔法がクラス クロージャーからパッケージ スコープを作成した後。

Mooseは、コンストラクターのロジックを操作できるようにするために、特にBUILDサブルーチンを探します。私の推測では (完全に追跡したわけではありませんが)、MooseX モジュールは Moose がやろうとしていることの邪魔にならないということです。そのため、コンストラクターのロジックを決定するためにネイティブBUILDが Moose マジックに永遠に渡されます。

一方、methodキーワードは、メタ クラス構造でメソッドを作成するDevel::Declareマジックです。

于 2009-07-20T21:47:48.623 に答える