2012-06-03 2 views
7

Gibt es eine CPAN-Standardmethode, um alle Superklassen einer Perl-Klasse (oder besser noch des gesamten Superklassenbaums, bis UNIVERSAL) zu finden?Was ist die beste Vorgehensweise, um alle Superklassen einer Perl-Klasse zu finden?

Oder ist die beste Praxis, einfach zu überprüfen @{"${$class}::ISA"} für jede Klasse, Eltern der Eltern usw. ...?

+1

Ist das vielleicht eine Trickfrage, deren Antwort Sie wollen das nicht tun? Manchmal solltest du Polymorphismus einfach machen lassen. Normalerweise sogar vielleicht. – tchrist

+0

@tchrist - kein Trick. Ich musste das nie tun (wie in deinem Kommentar und den Antworten erwähnt, ist es nicht etwas, das man normalerweise tun sollte); so dass, wenn die Notwendigkeit zu berücksichtigen, "wie" entstand bei der Beantwortung [this] (http://stackoverflow.com/questions/10869511/is-there-a-way-to-know-the-methods-ofan-instance) -von-einer-unbekannten-Klasse-in-perl/10869712 # 10869712), war ich mit der Notwendigkeit konfrontiert, eine AN-Implementierung auszuwählen. Und ich glaube fest an TIMTOWTDIBSWABTO. – DVK

Antwort

8

Es gibt keinen "Standardweg", da dies keine Standardaufgabe ist. Für alles andere als Visualisierung ist es eine rote OO-Flagge, Ihren Erbbaum zu untersuchen.

Zusätzlich zur Klasse :: ISA gibt es mro::get_linear_isa(). Beide waren eine Zeit lang im Kern, so dass sie für eine Definition als "Standard" angesehen werden konnten. Beide zeigen Vererbung als flache Liste, nicht als Baum, was vor allem für tiefe Magie nützlich ist.

Die perl5i meta object bietet sowohl linear_isa(), wie MRO (es nur nennt MRO) und ISA(), die die Klasse zurückgibt @ISA. Es kann verwendet werden, um einen Baum unter Verwendung einfacher Rekursion zu konstruieren, ohne in Symboltabellen zu gelangen.

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

"Für eine Weile" - könnten Sie das bitte quantifizieren? 5.12+? 5.8+? – DVK

+0

Macht nichts. Zu faul für Google. "Class :: ISA wurde in Release 5.8.0 in den Perl Core eingeführt" (aus ["Hidden Treasures of Perl Core" @ perl.com] (http://www.perl.com/pub/2003/05/29) /treasures.html)); – DVK

+0

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

1

Ich glaube nicht, dass es so etwas wie einen "Standard-CPAN-Weg" gibt. Prüfungs @ISA ist gängige Praxis - und auch plausibel, da Techniken wie use base qw(...) und use parent -norequire, ... arbeiten auch auf der @ISA ...

+0

"Standard" wie in "Text verwenden: CSV {_XS}?" ist Standard für CSV-Parsing. Ja, es gibt eine gazillion Module für CSV-Analyse, aber diese oder 1-2 andere sind am ausgereiftesten, von der überwiegenden Mehrheit der Entwickler usw. verwendet ... – DVK

+0

OK, Punkt genommen. Nun, auf jeden Fall würde ich es in Erwägung ziehen, '@ ISA' als den" Standard "zu betrachten. – mjhennig

4

Ich denke, Class::ISA ist so etwas wie Sie suchen

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

Drucke:

Mojo 
Mojo::Base 

Es ist jedoch keine Art von "Best Practice", da die Perl-Programmierer die ganze Aufgabe nicht jeden Tag erledigen.

0

Wahrscheinlich in diesen Tagen wollen Sie von mro, wie mro::get_linear_isa eine der Funktionen verwenden.

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

Rückgabetyp von 'mro :: get_linear_isa' ist kein Array, sondern arrayref !! – mikyra

Verwandte Themen