2009-06-29 9 views
6

Saludos,-Tratar con varios constructores heredada en Moose

estoy aprendiendo Moose y yo estoy tratando de escribir una subclase CGI::Application con Moose, que se hace difícil por el hecho de que la CGI-App no ​​se basa en Alce.

En mis otras subclases CGI-App, me gusta tener una clase padre con un método setup que examina la tabla de símbolos de la clase secundaria y configura automáticamente los modos de ejecución. Me imagino que puedo usar las instalaciones de metaclase de Moose para lograr lo mismo de una manera más limpia. Así que aquí es lo que tengo en mi clase padre:

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 
         ); 
    } 

} 

... y en mi clase hija:

use MooseX::Declare; 

class MyApp::CGI::Login 
extends MyApp::CGI { 
    method rm_main { 
     return "it works"; 
    } 
} 

me di cuenta de que la razón de mis runmodes no estaban recibiendo configurado correctamente se debe a que es setup llamado por el constructor de la aplicación CGI, y Moose::Object está pegando su propio constructor en mi clase. Me tratado de resolver esto con un modificador método:

around new { 
    $self = $orig->(@_); 
    $self->CGI::Application::new(@_); 
} 

Sin embargo, esto me da

Can't call method "BUILDARGS" on unblessed reference at ...Moose/Object.pm line 21. 

Tengo la sensación, que voy sobre esto en el camino equivocado por completo, y tiene Moose una facilidad mucho mejor para lograr lo que quiero, que aún no he descubierto.

Respuesta

9

¿Ya ha consultado Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent y MooseX::NonMoose?

Actualización: No estoy muy familiarizado con Moose y las técnicas surtidas. No pude obtener los módulos para compilar utilizando MooseX::Declare y MooseX::NonMoose juntos. Sin embargo, aquí es algo que parece funcionar:

base de aplicaciones de Clase

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" 

clase derivada

package My::Login; 
use Moose; 
extends 'My::App'; 

sub rm_main { 'it works!' } 

"My::Login" 

Guión

#!/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; 

salida

C:\Temp\f> t 
Content-Type: text/html; charset=ISO-8859-1 

it works! 
+2

Gracias. No pude hacer que MooseX :: NonMoose funcionara correctamente, pero pude hacer que mi clase base heredara la aplicación CGI correctamente con la receta del Cookbook. – friedo

+1

@friedo Gracias por aceptar mi respuesta. Estoy pensando que debe haber una manera de hacer que 'MooseX :: Declare' juegue bien con' MooseX :: NonMoose', pero esto no pude resolverlo. –

Cuestiones relacionadas