来自 Moose BUILD 方法的呱呱叫

发布于 2024-12-09 16:42:09 字数 1140 浏览 1 评论 0原文

如果 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

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

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 似乎不受影响。

我已经为此苦苦挣扎有一段时间了,似乎无法弄清楚到底是什么把事情搞砸了。

谢谢。

I want my class to blow up if the BUILD method fails. However, if I use croak to handle the error, the error gets reported from Class/MOP/Method.pm, rather than the caller's code. (That is to say, the caller who instantiates the object.) IOW, croak isn't barking far enough up the call tree.

Behold:

package Test;

use Moose;
use Carp 'croak';

sub BUILD {
    croak 'u r dum';
}

1;

Instantiating Test results in:

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

Carp.pm is supposed to pay attention to a package variable called @CARP_NOT to know which packages to avoid, but it seems to only pay attention to one item on the list. For example, if I add this to my Test.pm:

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

Then the result is:

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

So I should just add that to the array as well, right?

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

Then the result is still:

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

Moose::Object seems unaffected.

I've been banging my head against this for a while now and can't seem to figure out what's messing it up.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人九事 2024-12-16 16:42:09

make_immutable 似乎可以解决这个问题。当然,如果您确实需要您的类是可变的,我不知道该怎么办。

如果没有 make_immutableTest->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;

Output:

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

From 驼鹿::食谱::基础知识::食谱7

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

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

make_immutable seems to fix that. Of course, I don't know what to do if you do need your classes to be mutable.

Without make_immutable, Test->new invokes Moose::Object->new. If you look at the confess output, you'll note:

    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;

Output:

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

From Moose::Cookbook::Basics::Recipe7:

Second, you can no longer make changes via the metaclass API, such as adding attributes. In practice, this won't be a problem, as you rarely need to do this after first loading the class.

We strongly recommend you make your classes immutable. It makes your code much faster, with a small compile-time cost. This will be especially noticeable when creating many objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文