2009-06-29 14 views
6

Saluti,Trattare con i costruttori più-ereditato a Moose

sto imparando Moose e sto cercando di scrivere una sottoclasse CGI::Application con Moose, che è resa difficile dal fatto che CGI-App non si basa su Moose.

Nelle altre sottoclassi CGI-App, mi piace avere una classe genitore con un metodo setup che esamina la tabella dei simboli della classe figlia e imposta automaticamente i runmodes. Immagino di poter utilizzare le strutture di metameralità di Moose per ottenere la stessa cosa in un modo più pulito. Così qui è quello che ho nella mia classe genitore:

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

} 

... e nella mia classe figlio:

use MooseX::Declare; 

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

mi sono reso conto che la ragione le mie runmodes non erano sempre impostato correttamente perché setup è chiamato dal costruttore CGI-App e Moose::Object sta attaccando il proprio costruttore nella mia classe. Ho cercato di risolvere questo con un metodo modificatore:

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

Questo mi dà

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

Ho la sensazione, però, che ho intenzione di questo in tutto il modo sbagliato, e Moose ha una struttura molto migliore per ottenere ciò che voglio, che non ho ancora scoperto.

risposta

9

Avete già visto Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent e MooseX::NonMoose?

Update: Io non sono molto familiare con Moose e le tecniche assortite. Non ero in grado di compilare i moduli utilizzando MooseX::Declare e MooseX::NonMoose insieme. Tuttavia, qui è una cosa che sembra funzionare:

Applicazione Base Class

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" 

classe derivata

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

sub rm_main { 'it works!' } 

"My::Login" 

Script

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

uscita

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

it works! 
+2

Grazie. Non ero in grado di far funzionare correttamente MooseX :: NonMoose, ma ero in grado di far ereditare correttamente la mia classe base da CGI-App con la ricetta del ricettario. – friedo

+1

@friedo Grazie per aver accettato la mia risposta. Sto pensando che ci debba essere un modo per far sì che 'MooseX :: Declare' giochi con' MooseX :: NonMoose' ma questo non riuscivo a capirlo. –