Problema com mixins em um MooseX :: class NonMoose
Pergunta
Considere o seguinte:
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;
...
A saída quando Isso compila é:
begin isa = $VAR1 = [
'Moose::Object'
];
runtime isa = $VAR1 = [
'CGI::Application',
'Moose::Object'
];
Por que eu me importo? Porque quando eu tento use
um CGI :: Application :: Plugin :: * classe, ele espera que eu seja herdando de CGI::Application
em tempo de compilação já. As tentativas de classe plugin para chamar add_callback
como um método de classe em minha classe, mas não pode, porque a minha @ISA
não está configurado ainda.
Qual é a melhor maneira de resolver isso? Será que ajustes @ISA
manualmente em um bloco BEGIN
interferir com MooseX::NonMoose
?
Editar
Os seguintes parece funcionar, mas acho que é ofensiva:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use base 'CGI::Application';
extends 'CGI::Application';
Eu não sei o suficiente (ou qualquer coisa, na verdade) sobre o funcionamento interno alces de saber se esta é uma boa idéia.
Solução
Eu não encontrar use base 'CGI::Application'; extends 'CGI::Application';
ser terrivelmente medonho porque ele faz exatamente o que você precisa:
- em tempo de compilação,
@ISA
contém'CGI::Application'
, o que exatamente satisfaz os requisitos de uso de CGI :: Application :: Plugin :: * - No momento da execução, sua classe é um Moose descendente de CGI :: Aplicação , com todos os benefícios que se seguiram (sendo capaz de projetar a composição da sua classe com Moosey meta a Deus). É apenas após a linha
extends 'CGI::Application'
é encontrado que qualquer trabalho é feito (ou seja, métodos são chamados na sua classe), que contam com o trabalho feito pela declaraçãoextends
:. Que seus desce classe deMoose::Object
e você tem uma meta-classe instalado
Dito isso, a solução da jrockway também deve funcionar:
BEGIN { extends 'CGI::Application' }
... onde você obtém todas as meta bondade Moosey apenas um pouco à frente do cronograma de quando você precisar dele, e ele não deve ser muito antes do previsto, desde que você já chamou use Moose
e use MooseX::NonMoose
para definir extends
.
(Adendo: Agora eu estou ponderando as complexidades complilational de criar a capacidade de forçar a análise de uma palavra-chave em tempo de compilação que são analisados ??imediatamente, como se eles estavam embrulhados em um bloco BEGIN
por exemplo, algo como. se Moose.pm declarou use compiletime qw(extends)
. seria um bom pedaço de açúcar sintático com certeza.)