2012-06-03 7 views
7

¿Existe una manera estándar de CPAN de averiguar todas las superclases de una clase Perl (o mejor aún todo un árbol de superclase, hasta UNIVERSAL)?¿Cuál es la mejor práctica para descubrir todas las superclases de una clase Perl?

¿O es la mejor práctica simplemente examinar @{"${$class}::ISA"} para cada clase, los padres de la clase, etc. ...?

+1

¿Es esta quizás una pregunta capciosa cuya respuesta es que usted no quiere hacer eso? A veces deberías dejar que el polimorfismo haga su trabajo. Por lo general incluso, tal vez. – tchrist

+0

@tchrist - no hay truco. Nunca tuve que hacer eso (como notaron su comentario y las respuestas, no es algo que uno normalmente debería hacer); de modo que cuando surge la necesidad de considerar "cómo" al responder [esto] (http://stackoverflow.com/questions/10869511/is-there-a-way-to-know-the-methods-of-an-instance -of-an-unknown-class-in-perl/10869712 # 10869712), tuve que enfrentar la necesidad de elegir una implementación AN. Y soy un firme creyente en TIMTOWTDIBSWABTO. – DVK

Respuesta

8

No hay una "forma estándar" porque esto no es lo estándar que desea hacer. Para cualquier cosa que no sea la visualización, es una bandera roja de OO que desea inspeccionar su árbol de herencia.

Además de Class :: ISA, hay mro::get_linear_isa(). Ambos han estado en core por un tiempo, por lo que podrían considerarse "estándar" para cierta definición. Ambos muestran la herencia como una lista plana, no como un árbol, que es útil sobre todo para la magia profunda.

El perl5i meta object proporciona tanto linear_isa(), como MRO (que sólo llama a MRO), y ISA() que devuelve la clase @ISA. Se puede usar para construir un árbol usando recursión simple sin ingresar a tablas de símbolos.

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

"Por un tiempo" - ¿podría cuantificar eso por favor? 5.12+? 5.8+? – DVK

+0

No importa. Demasiado perezoso para Google. "Class :: ISA se introdujo en Perl Core en la versión 5.8.0" (de ["Hidden Treasures of Perl Core" @ perl.com] (http://www.perl.com/pub/2003/05/29 /treasures.html)); – DVK

+0

@DVK Véase también [corelist] (http://search.cpan.org/perldoc?corelist) – Schwern

1

No creo que haya algo así como una "forma de CPAN estándar". Examinar @ISA es una práctica común - y también verosímil, ya que las técnicas como use base qw(...) y use parent -norequire, ... también operan en la parte superior de @ISA ...

+0

"estándar" como en "Usar texto :: CSV {_XS}?" es estándar para el análisis de CSV. Sí, hay un montón de módulos para el análisis de CSV, pero este u otros 1-2 son más maduros, utilizados por la gran mayoría de los desarrolladores, etc ... – DVK

+0

OK, punto tomado. Bueno, de cualquier manera, consideraría examinar '@ ISA' como el" estándar "en ese momento. – mjhennig

4

Creo Class::ISA es algo así como que están en busca de

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

Prints:

Mojo 
Mojo::Base 

Sin embargo, no es una especie de "mejor práctica" ya que la tarea no es algo que los programadores de Perl hagan todos los días.

0

más probable es que en estos días que desea utilizar una de las funciones de mro, como mro::get_linear_isa.

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

tipo de devolución de 'mro :: get_linear_isa' no es array sino arrayref !! – mikyra

Cuestiones relacionadas