Проблема с миксинами в классе MooseX :: NonMoose - PullRequest
5 голосов
/ 01 ноября 2009

Рассмотрим следующее:

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';

Я не знаю достаточно (или вообще ничего) о внутренностях Муз, чтобы понять, хорошая ли это идея.

1 Ответ

5 голосов
/ 01 ноября 2009

Я не считаю 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). Это был бы хороший кусок синтаксического сахара наверняка.)

...