#perl #moose #carp
#perl #moose #карп
Вопрос:
Я хочу, чтобы мой класс взорвался, если 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:
make_immutable
кажется, это исправлено. Конечно, я не знаю, что делать, если вам нужно, чтобы ваши классы были изменяемыми.
Без make_immutable
, Test->new
вызывает Moose::Object->new
. Если вы посмотрите на confess
результат, вы заметите:
Вызывается Test::BUILD(...) ... Вызывается класс ::MOP::Метод::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 u r dum в конструкторе Test::new (определено в ./t.pl строка 14) строка 28
Из Moose :: Поваренная книга ::Основы::Recipe7:
Во-вторых, вы больше не можете вносить изменения через API metaclass, такие как добавление атрибутов. На практике это не будет проблемой, так как вам редко нужно делать это после первой загрузки класса.
…
Мы настоятельно рекомендуем вам сделать ваши классы неизменяемыми. Это делает ваш код намного быстрее с небольшими затратами времени на компиляцию. Это будет особенно заметно при создании многих объектов.
Комментарии:
1. Ах, я даже не подумал об этом. Я всегда делаю
->make_immutable
это как запоздалую мысль после того, как заканчиваю уточнять класс.2. @friedo, пообещав больше не изменять класс во время текущего запуска , Moose создает эффективный конструктор для вашего класса. Это не мешает вам вообще менять модуль.
3. Я знаю — я должен добавить его в свой шаблон пакета вместо того, чтобы пытаться не забыть добавить его, когда я закончу.
4. К сожалению, это не работает для модификатора
before
метода.