квакающий из метода Moose BUILD - PullRequest
4 голосов
/ 15 октября 2011

Я хочу, чтобы мой класс взорвался, если метод 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, кажется, не затронут.

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

Спасибо.

1 Ответ

6 голосов
/ 15 октября 2011

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;

Вывод:

[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 метакласса, такие как добавление атрибутов.На практике это не будет проблемой, так как вам редко нужно делать это после первой загрузки класса.

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

...