4

BUILDメソッドが失敗した場合にクラスを爆破させたい。ただし、croakエラーの処理に使用する場合、エラーはClass/MOP/Method.pm呼び出し元のコードではなく、から報告されます。(つまり、オブジェクトをインスタンス化する呼び出し元です。)IOWcroakは、呼び出しツリーを十分に吠えていません。

見よ:

package Test;

use Moose;
use Carp 'croak';

sub BUILD {
    croak 'u r dum';
}

1;

Test結果をインスタンス化すると、次のようになります。

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Class/MOP/Method.pm line 125

Carp.pm避けるべきパッケージを知るために呼び出されるパッケージ変数に注意を払うことになって@CARP_NOTいますが、リストの1つの項目にしか注意を払っていないようです。たとえば、これを自分のTest.pm:に追加すると

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

その結果は次のとおりです。

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59

だから私はそれを配列にも追加する必要がありますよね?

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

その後、結果はまだです:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59

Moose::Object影響を受けていないようです。

私はしばらくの間これに頭をぶつけてきました、そしてそれを台無しにしているものを理解することができないようです。

ありがとう。

4

1 に答える 1

6

make_immutableそれを修正するようです。もちろん、クラスを変更可能にする必要がある場合はどうすればよいかわかりません。

なしmake_immutableで、 をTest->new呼び出しますMoose::Object->new。出力を見ると、次のconfessことがわかります。

    Test::BUILD(...) が呼び出されました ...
    Class::MOP::Method::execute(...) が呼び出されました ...
    Moose::Object::BUILDALL(...) が呼び出されました ...
    Moose::Meta::Class::new_object(...) が呼び出されました ...
    Moose::Object::new('Test') が ./t.pl 行 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;

出力:

[sinan@archardy tmp]$ ./t.pl
ur dum at constructor Test::new (./t.pl 14 行目で定義) 28 行目

Moose::Cookbook::Basics::Recipe7から:

次に、属性の追加など、メタクラス API を介して変更を行うことができなくなりました。実際には、クラスを最初にロードした後にこれを行う必要はほとんどないため、これは問題になりません。

…</p>

クラスを不変にすることを強くお勧めします。これにより、コンパイル時のコストがわずかに抑えられ、コードが大幅に高速化されます。これは、多くのオブジェクトを作成する場合に特に顕著になります。

于 2011-10-15T00:37:55.730 に答える