4

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

看哪:

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来知道要避免哪些包,但它似乎只注意列表中的一项。例如,如果我将此添加到我的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(...) 调用...
    类::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
你在构造函数 Test::new 中的 dum(在 ./t.pl 第 14 行定义)第 28 行

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

其次,您不能再通过元类 API 进行更改,例如添加属性。实际上,这不会成为问题,因为您很少需要在首次加载类后执行此操作。

…</p>

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

于 2011-10-15T00:37:55.730 回答