2009-11-05 10 views
10

Sapete come Moose si attiva automaticamente strict e warnings durante l'importazione? Voglio estendere questo comportamento attivando autodie e use feature ':5.10' nelle mie classi di Alci.Come posso estendere le esportazioni pragma automatiche di Moose?

ho rintracciato in cui Moose fa questo, in Moose::Exporter, che assembla un costume import sub per Moose che chiama strict->import e warnings->import per la classe chiamata.

Tuttavia, non riesco a capire un modo per estendere questo metodo di importazione in un modo Moose-ish.

Come devo gestirlo?

http://www.friedo.com/bullwinkle.gif

risposta

2

Poiché è possibile che un modulo esporti le sue funzioni nello spazio dei nomi use -ing, è possibile che sia necessario eseguire alcune operazioni di scavo del codice per implementare ciascuna libreria desiderata. Quello che stai chiedendo non è nulla di specifico per Moose, quindi puoi scrivere il tuo o il modulo di best practice della tua azienda che stabilirà un gruppo di standard con cui lavorare, ad es.

use OurCompany::BestPractices::V1; 

con

package OurCompany::BestPractices::V1; 

use strict; 
use warnings; 
use feature (':5.10'); 
require Fatal; 
require Moose; 

# Required for straight implementation of autodie code 
our @ISA; 
push @ISA, qw(
    Fatal 
); 

sub import { 
    my $caller = caller; 
    strict->import; 
    warnings->import; 
    feature->import(':5.10'); 
    Moose->import ({into => $caller}); 

    #autodie implementation copied from autodie source 
    splice(@_,1,0,Fatal::LEXICAL_TAG); 
    goto &Fatal::import; 
} 

1; 

Autodie rende le cose un po 'più complicata dato che si basa sulla ricerca di pacchetti di l'uso-er da chiamante() e utilizza il goto, ma si può essere in grado di trovare una migliore modo con più test. Quanto più implementerai, tanto più complicata sarà questa libreria, ma potrebbe essere di valore abbastanza alto per te da avere la soluzione one-off che puoi usare all'interno di tutti voi o il codice della vostra azienda.

+0

Grande esempio, grazie – friedo

+0

Ho finito per usare una variazione di questa idea. – friedo

1

è necessario definire un sub chiamato importazione nel pacchetto, e importare tutte le altre cose lì.

Un esempio da Modern :: Perl (un altro modulo politica si potrebbe guardare):

use 5.010_000; 

use strict; 
use warnings; 

use mro (); 
use feature(); 

sub import { 
    warnings->import(); 
    strict->import(); 
    feature->import(':5.10'); 
    mro::set_mro(scalar caller(), 'c3'); 
} 

Aggiornamento: Ci dispiace, non ha letto la questione con sufficiente attenzione.

Un buon modo per estendere un metodo di importazione esistente è scriverne uno nuovo in un nuovo pacchetto e richiamare il metodo di importazione di Moose da lì. Puoi farlo sottoclasse, forse puoi usare anche Moose per questo ;-)

5

Il mio approccio risolve il problema all'indietro.

Perché non utilizzare ToolSet per creare un gruppo di use istruzioni che include Moose, insieme ai vostri pragmi aggiuntivi?

Il codice dovrebbe essere simile:

# MagicMoose.pm 
package MagicMoose; 

use base 'ToolSet'; 

ToolSet->use_pragma(qw/feature :5.10/); # perl 5.10 
ToolSet->use_pragma(qw/autodie/); 

# define exports from other modules 
ToolSet->export(
    'Moose'   => undef,  # get the defaults 
); 

1; # modules must return true 

non ho ancora testato questo. Francamente, ho appena trovato ToolSet alcuni giorni fa e non ho ancora avuto la possibilità di provarlo. FWIW, le recensioni sono positive.

+0

Grazie per il suggerimento. Non avevo sentito parlare di ToolSet; Sto indagando ora. – friedo

2

Moose::Exporter consente di definire un metodo personalizzato import per una classe di zucchero che si sta utilizzando. MooseX::POE ha usato una versione di questo per anni, ma lo fa in quello che considero un modo "hackish".Guardando la documentazione per Moose::Exporter il seguente dovrebbe essere più o meno quello che stai chiedendo

package Modern::Moose; 
use Moose(); 
use Moose::Exporter; 

my ($import) = Moose::Exporter->build_import_methods(
    also => 'Moose', 
    install => [qw(unimport init_meta)], 
); 

sub import { # borrowing from mortiz's answer for feature/mro 
    feature->import(':5.10'); 
    mro::set_mro(scalar caller(), 'c3');   
    goto &$import; 
} 

Questo può quindi essere utilizzato in questo modo

package MyApp; 
use Modern::Moose; 

has greeting => (is => 'ro', default => 'Hello'); 
sub run { say $_[0]->greeting } # 5.10 is enabled 
+0

Grazie! Domani darò uno scatto più tardi e vedrò se riesco a capirlo. – friedo

Problemi correlati