2012-06-03 12 views
7

Esiste un modo CPAN standard per scoprire tutte le superclassi di una classe Perl (o meglio ancora di un albero superclasse, fino a UNIVERSAL)?Qual è la migliore pratica per scoprire tutte le superclassi di una classe Perl?

Oppure è la migliore pratica per esaminare semplicemente @{"${$class}::ISA"} per ogni classe, i genitori della classe, ecc ...?

+1

Questa è forse una domanda trabocchetto la cui risposta è che non vuoi farlo? A volte dovresti lasciare che il polimorfismo faccia il suo esempio. Di solito anche, forse. – tchrist

+0

@tchrist - nessun trucco. Non ho mai dovuto farlo (come notato dal tuo commento e dalle risposte, non è qualcosa che si dovrebbe fare di solito); in modo che quando la necessità di considerare "come" è sorto quando si risponde a [questo] (http://stackoverflow.com/questions/10869511/is-there-a-----------modifica-di-metodi-di-an-instance -of-an-unknown-class-in-perl/10869712 # 10869712), mi sono trovato di fronte alla necessità di scegliere un'implementazione AN. E credo fermamente in TIMTOWTDIBSWABTO. – DVK

risposta

8

Non esiste un "metodo standard" perché non è una cosa standard che si desidera eseguire. Per qualsiasi cosa diversa dalla visualizzazione, è una bandiera rossa OO per voler ispezionare il tuo albero ereditario.

In aggiunta alla classe :: ISA, c'è mro::get_linear_isa(). Entrambi sono stati al centro per un po ', quindi potrebbero essere considerati "standard" per alcune definizioni. Entrambi mostrano ereditarietà come una lista piatta, non un albero, che è utile soprattutto per la magia profonda.

Il perl5i meta object fornisce sia linear_isa(), come MRO (solo chiamate MRO), e ISA() che restituisce la classe @ISA. Può essere usato per costruire un albero usando la ricorsione semplice senza entrare nelle tabelle dei simboli.

use perl5i::2; 

func print_isa_tree($class, $depth) { 
    $depth ||= 0; 

    my $indent = " " x $depth; 
    say $indent, $class; 

    for my $super_class ($class->mc->ISA) { 
     print_isa_tree($super_class, $depth+1); 
    } 

    return; 
} 


my $Class = shift; 
$Class->require; 

print_isa_tree($Class); 

__END__ 
DBIx::Class 
    DBIx::Class::Componentised 
     Class::C3::Componentised 
    DBIx::Class::AccessorGroup 
     Class::Accessor::Grouped 
+0

"Per un po '", potresti quantificarlo per favore? 5.12+? 5.8+? – DVK

+0

Non importa. Troppo pigro per Google. "Class :: ISA è stato introdotto nel Perl Core nella versione 5.8.0" (da ["Hidden Treasures of Perl Core" @ perl.com] (http://www.perl.com/pub/2003/05/29 /treasures.html)); – DVK

+0

@DVK Vedi anche [corelist] (http://search.cpan.org/perldoc?corelist) – Schwern

1

Non credo che esista un "modo standard CPAN". Esaminando @ISA è pratica comune - e anche plausibile, dal momento che tecniche come use base qw(...) e use parent -norequire, ... operano anche in cima @ISA ...

+0

"standard" come in "Usa testo: CSV {_XS}?" è standard per l'analisi CSV. Sì, ci sono moduli di gazillion per l'analisi CSV ma questo o altri 1-2 sono più maturi, usati dalla stragrande maggioranza degli sviluppatori ecc ... – DVK

+0

OK, punto preso. Bene, in entrambi i casi, prenderei in considerazione l'esame di "@ ISA" come "standard" allora. – mjhennig

4

Penso Class::ISA sia qualcosa come voi sono alla ricerca di

use Class::ISA; 
use Mojolicious; 
print join "\n", Class::ISA::super_path("Mojolicious"); 

Stampe:

Tuttavia, non è una sorta di "best practice" poiché l'intero compito non è qualcosa che i programmatori Perl fanno ogni giorno.

0

Molto probabilmente in questi giorni che si desidera utilizzare una delle funzioni da mro, come ad esempio mro::get_linear_isa.

use mro; 
my @superclasses = mro::get_linear_isa($class); 
+0

il tipo di ritorno di 'mro :: get_linear_isa' non è array ma arrayref !! – mikyra

Problemi correlati