从Moose BUILD方法中呱呱叫

fri*_*edo 4 perl moose carp

如果BUILD方法失败,我希望我的班级爆炸.但是,如果我croak用来处理错误,则会报告错误Class/MOP/Method.pm,而不是调用者的代码.(也就是说,实例化对象的调用者.)IOW,croak在调用树上没有吠叫.

看吧:

package Test;

use Moose;
use Carp 'croak';

sub BUILD {
    croak 'u r dum';
}

1;
Run Code Online (Sandbox Code Playgroud)

实例化Test结果:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Class/MOP/Method.pm line 125
Run Code Online (Sandbox Code Playgroud)

Carp.pm应该注意一个名为变量的包变量@CARP_NOT来知道要避免哪些包,但它似乎只关注列表中的一个项目.例如,如果我将其添加到我的Test.pm:

our @CARP_NOT = ( 'Class::MOP::Method' );
Run Code Online (Sandbox Code Playgroud)

然后结果是:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59
Run Code Online (Sandbox Code Playgroud)

所以我也应该将添加到数组中,对吧?

our @CARP_NOT = ( 'Class::MOP::Method', 'Moose::Object'  );
Run Code Online (Sandbox Code Playgroud)

然后结果仍然是:

u r dum at /home/friedo/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/Moose/Object.pm line 59
Run Code Online (Sandbox Code Playgroud)

Moose::Object 似乎没有受到影响.

我现在一直在反对这个问题,现在似乎无法弄清楚是什么弄乱了它.

谢谢.

Sin*_*nür 6

make_immutable似乎解决了这个问题.当然,如果你确实需要你的课程是可变的,我不知道该怎么办.

没有make_immutable,Test->new调用Moose::Object->new.如果你看一下confess输出,你会注意到:

    Test::BUILD(...) called ...
    Class::MOP::Method::execute(...) called ...
    Moose::Object::BUILDALL(...) called ...
    Moose::Meta::Class::new_object(...) called ...
    Moose::Object::new('Test') called at ./t.pl line 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;
Run Code Online (Sandbox Code Playgroud)

输出:

[sinan@archardy tmp]$ ./t.pl
u r dum at constructor Test::new (defined at ./t.pl line 14) line 28

来自Moose :: Cookbook :: Basics :: Recipe7:

其次,您无法再通过元类API进行更改,例如添加属性.在实践中,这不会是一个问题,因为在首次加载类之后很少需要这样做.

...

我们强烈建议您使您的类不可变.它使您的代码更快,编译时成本很低.在创建许多对象时,这一点尤其明显.