Проблема с миксинами в классе MooseX::NonMoose
Учтите следующее:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use Data::Dumper;
extends 'CGI::Application';
BEGIN {
print "begin isa = " . Dumper \@MyApp::CGI::ISA;
};
print "runtime isa = " . Dumper \@MyApp::CGI::ISA;
...
Выходные данные при компиляции:
begin isa = $VAR1 = [
'Moose::Object'
];
runtime isa = $VAR1 = [
'CGI::Application',
'Moose::Object'
];
Почему меня это волнует? Потому что когда я пытаюсь use
CGI::Application::Plugin::* класс, он ожидает, что я наследую от CGI::Application
уже во время компиляции. Класс плагина пытается вызвать add_callback
как метод класса в моем классе, но не могу, потому что мой @ISA
еще не настроен.
Какой лучший способ решить это? Будет настройка @ISA
вручную в BEGIN
блокировать мешать MooseX::NonMoose
?
редактировать
Следующее, кажется, работает, но я считаю это оскорбительным:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use base 'CGI::Application';
extends 'CGI::Application';
Я не знаю достаточно (или вообще ничего) о внутренностях Moose, чтобы понять, хорошая ли это идея.
1 ответ
Не нахожу use base 'CGI::Application'; extends 'CGI::Application';
быть ужасно страшным, потому что он делает именно то, что вам нужно:
- Во время компиляции
@ISA
содержит'CGI::Application'
, который точно соответствует требованиям использования CGI::Application::Plugin::* - Во время выполнения ваш класс является потомком Moose CGI:: Application, со всеми вытекающими отсюда преимуществами (способностью создавать композицию вашего класса с помощью мета-бога Moosey). Это только после
extends 'CGI::Application'
обнаруживается, что любая работа выполнена (т.е. методы вызываются в вашем классе), которые полагаются на работу, выполненнуюextends
утверждение: что ваш класс происходит отMoose::Object
и у вас установлен метакласс.
Тем не менее, решение jrockway также должно работать:
BEGIN { extends 'CGI::Application' }
... где вы получаете всю мета-доброту Moosey только немного раньше графика, когда вам это нужно, и это не должно быть слишком досрочно, если вы уже звонили use Moose
а также use MooseX::NonMoose
для того, чтобы определить extends
,
(Приложение. Теперь я размышляю над сложностями компиляции, связанными с созданием возможности принудительного разбора ключевого слова во время компиляции, который анализируется немедленно, например, если он был обернут в BEGIN
блок. например, что-то вроде, если Moose.pm объявлен use compiletime qw(extends)
, Это был бы хороший кусок синтаксического сахара наверняка.)