Квакающий из метода Moose BUILD

Я хочу, чтобы мой класс взорвался, если BUILD метод не удался. Однако, если я использую croak чтобы обработать ошибку, об ошибке сообщают от Class/MOP/Method.pm, а не код звонящего. (То есть вызывающий объект, который создает экземпляр объекта.) 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 кажется незатронутым.

Я бился головой об это некоторое время и не могу понять, что все это портит.

Благодарю.

1 ответ

Решение

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 в конструкторе Test::new (определено в./t.pl строка 14) строка 28

От лося:: Кулинарная книга:: Основы:: Recipe7:

Во-вторых, вы больше не можете вносить изменения через API метакласса, такие как добавление атрибутов. На практике это не будет проблемой, так как вам редко нужно делать это после первой загрузки класса.

...

Мы настоятельно рекомендуем сделать ваши занятия неизменными. Это делает ваш код намного быстрее, с небольшими затратами времени компиляции. Это будет особенно заметно при создании множества объектов.

Другие вопросы по тегам