Работа с несколькими наследуемыми конструкторами в Moose
Привет,
Я изучаю Moose и пытаюсь написать подкласс CGI::Application для Moose, что осложняется тем, что CGI-App не основано на Moose.
В других моих подклассах CGI-App мне нравится иметь родительский класс с setup
метод, который просматривает таблицу символов дочернего класса и автоматически устанавливает режимы выполнения. Я полагаю, что могу использовать средства метакласса Moose, чтобы добиться того же самого более чистым способом. Итак, вот что я имею в своем родительском классе:
use MooseX::Declare;
class MyApp::CGI
extends Moose::Object
extends CGI::Application {
method setup {
$self->start_mode( 'main' );
my @methods = map { $_->name } $self->meta->get_all_methods;
$self->run_modes( map { /^rm_(.+)$/ => $_ }
grep { /^rm_/ }
@methods
);
}
}
... и в моем детском классе:
use MooseX::Declare;
class MyApp::CGI::Login
extends MyApp::CGI {
method rm_main {
return "it works";
}
}
Я понял, что причина, по которой мои режимы запуска не были настроены должным образом, заключается в том, что setup
вызывается конструктором CGI-App, и Moose::Object
вставляет свой собственный конструктор в моем классе. Я попытался решить это с помощью модификатора метода:
around new {
$self = $orig->( @_ );
$self->CGI::Application::new( @_ );
}
Это дает мне
Can't call method "BUILDARGS" on unblessed reference at ...Moose/Object.pm line 21.
Однако у меня есть ощущение, что я поступаю об этом совершенно неправильно, и у Муз есть гораздо лучшая возможность для достижения того, чего я хочу, чего я еще не обнаружил.
1 ответ
Вы уже смотрели на http://search.cpan.org/perldoc?Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent и MooseX:: NonMoose?
Обновление: я не очень знаком с Moose и различными методами. Я не смог получить модули для компиляции с помощью MooseX::Declare
а также MooseX::NonMoose
все вместе. Тем не менее, вот то, что, кажется, работает:
Базовый класс приложения
package My::App;
use Moose;
use MooseX::NonMoose;
extends 'CGI::Application';
sub setup {
my $self = shift;
$self->start_mode( 'main' );
$self->run_modes(
map { $_ = $_->name;
/^rm_ (?<rm>.+) $/x ? ( $+{rm} => $_ ) : ()
} $self->meta->get_all_methods
);
}
"My::App"
Производный класс
package My::Login;
use Moose;
extends 'My::App';
sub rm_main { 'it works!' }
"My::Login"
скрипт
#!/usr/bin/perl
use strict;
use warnings;
# For testing on the command line
use FindBin qw( $Bin );
use lib $Bin;
use My::Login;
my $app = My::Login->new;
$app->run;
Выход
C:\Temp\f> t
Content-Type: text/html; charset=ISO-8859-1
it works!