Wie durchlaufen Sie alle Methoden einer Klasse in Perl? Gibt es gute Online-Referenzen zu Perl-Introspektion oder Reflektion?Wie kann ich alle Methoden einer Klasse in Perl durchlaufen?
Antwort
Die Empfehlung, die Todd Gardner gab, um Elch zu verwenden, ist eine gute, aber der von ihm gewählte Beispielcode ist nicht sehr hilfreich.
Wenn Sie einen nicht-Elch mit Klasse Inspektion, würden Sie so etwas tun:
use Some::Class;
use Class::MOP;
my $meta = Class::MOP::Class->initialize('Some::Class');
for my $meth ($meta->get_all_methods) {
print $meth->fully_qualified_name, "\n";
}
Siehe Class::MOP::Class docs für weitere Details, wie Selbstbeobachtung zu tun.
Sie werden auch feststellen, dass ich Class :: MOP anstelle von Moose verwendet habe. Class :: MOP (MOP = Meta-Object Protocol) ist die Basis, auf der Moose baut. Wenn du mit Nicht-Moose-Klassen arbeitest, bringt dir die Verwendung von Moose zur Introspektion nichts.
Wenn Sie wollten, könnten Sie use Moose()
und Moose::Meta::Class->initialize
anstelle von CMOP.
+1: Das ist ordentlich, ich wusste nicht, dass Sie Class :: MOP so verwenden könnten. –
Ich erkläre die Grenzen dieser in meiner Antwort. Selbst mit einer leeren Klasse kann es die Methoden von UNIVERSAL nicht aufnehmen und kann keine von AUTOLOAD aufnehmen. –
@brian d foy: Verwenden von AUTOLOAD ist schlecht, mmmkay? – HoldOffHunger
Hängt davon ab, wenn Sie meinen, irgendeine Klasse, oder wenn Sie Ihre eigenen implementieren würden. Für letzteres verwende ich Moose, was eine sehr saubere Syntax für diese Funktionen bietet. Aus dem Kochbuch:
my %attributes = %{ $self->meta->get_attribute_map };
for my $name (sort keys %attributes) {
my $attribute = $attributes{$name};
if ( $attribute->does('MyApp::Meta::Attribute::Trait::Labeled')
# ... keeps on
Beachten Sie, dass Moose keine Attribute findet, es sei denn, die Klasse, die Sie inspizieren, wurde zuerst mit Moose definiert. Die Methodenintrospektion, wie auch die meisten anderen Bits, funktioniert jedoch gut. –
Im allgemeinen Fall, werden Sie die Symboltabelle überprüfen müssen (es sei denn, Sie Moose verwenden). Um zum Beispiel die Verfahren, die in dem Paket definierten IO::File
aufzulisten:
use IO::File;
no strict 'refs';
print join ', ', grep { defined &{"IO::File::$_"} } keys %{IO::File::};
Der Hash %{IO::File::}
ist die Symboltabelle der IO::File package
und die grep
filtert nicht-Subroutine Einträge (z.B. Paketvariablen).
Um dies auf vererbte Methoden zu erweitern, müssen Sie rekursiv die Symboltabellen der übergeordneten Klassen (@IO::File::ISA
) durchsuchen.
Hier ist ein komplettes Beispiel:
sub list_methods_for_class {
my $class = shift;
eval "require $class";
no strict 'refs';
my @methods = grep { defined &{$class . "::$_"} } keys %{$class . "::"};
push @methods, list_methods_for_class($_) foreach @{$class . "::ISA"};
return @methods;
}
Für weitere Informationen über Pakete und Symboltabellen finden Sie in der perlmod -Handbuchseite.
Nicht jede Methode muss in der Symboltabelle definiert sein, und Sie vermissen UNIVERSAL. –
Ich habe mich gefragt, ob irgendwelche Lösungen für diese Frage, besonders hier eine, eine neue Objektinstanz erzeugen, wenn der Code aufgerufen wird und wenn er wiederverwendet wird oder jede Instanz im Speicher verbleibt, bis das Programm beendet wird. Da Reflektion/Introspektion in einigen anderen Sprachen wie .NET und Java verwendet werden muss, muss sorgfältig darauf geachtet werden, wo die Klassenobjekt-Referenz instanziiert wird. Andernfalls können neue Instanzen pro Aufruf abgerufen werden. – David
Wahrscheinlich möchten Sie die Klasse :: Inspector-> Methoden ('Ihre :: Klasse').
Nuff sagte.
Sie können leicht eine Liste der definierten Methoden einer Klasse mit den bereits bereitgestellten Antworten erhalten. Perl ist jedoch eine dynamische Sprache, was bedeutet, dass später weitere Methoden definiert werden können. Es gibt wirklich keine Möglichkeit, eine Liste aller Methoden zu erhalten, mit denen eine bestimmte Klasse umgehen kann. Für viel mehr Details über diese Art von Sachen, habe ich ein paar Kapitel in Mastering Perl.
Die Leute geben Ihnen (und Upvoting) Antworten, ohne Ihnen von den Einschränkungen zu erzählen.
Adam erwähnt seine Class::Inspector, aber es funktioniert nicht wirklich, weil es versucht, etwas zu tun, was eine dynamische Sprache nicht tut (und das ist statisch :) Zum Beispiel ist hier ein Ausschnitt, in dem Class :: Inspector keine Methoden zurückgibt , aber ich kann immer noch die VERSION
Methode (sowie isa
und can
) nennen:
BEGIN {
package Foo;
our $VERSION = '1.23'
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports nothing
print Foo->VERSION, "\n";
Hier ist ein weiterer Fall, in dem ich eine Methode aufrufen kann ich mag, aber Klasse :: Inspektor gibt nur AUTOLOAD
(und fehlt noch VERSION
, isa
und can
):
BEGIN {
package Foo;
our $VERSION = '1.23';
my $object = bless {}, __PACKAGE__;
sub AUTOLOAD { $object }
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports only "AUTOLOAD"
print Foo->dog->cat->bird, "\n";
Seltsamerweise scheint jeder UNIVERSAL zu ignorieren, wahrscheinlich weil sie nicht explizit damit umgehen, da es nur virtuell in @ISA ist. Ich kann eine debug
Methode zu jeder Klasse hinzufügen und Class :: Inspektor noch fehlt es, obwohl es eine definierte Methode ist:
BEGIN {
sub UNIVERSAL::debug { "Hello debugger!\n" }
package Foo;
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # still reports nothing
print Foo->debug, "\n";
Class::MOP hat die gleichen Einschränkungen.
Nicht jedes Modul wird AUTOLOAD verwenden, aber es ist auch keine obskure oder seltene Funktion. Wenn es Ihnen nichts ausmacht, dass Sie einige der Methoden vermissen, dann könnte Class :: Inspector oder Class :: MOP in Ordnung sein. Es wird Ihnen nicht nur eine Liste aller Methoden geben, die Sie für eine Klasse oder ein Objekt in jedem Fall aufrufen können.
Wenn Sie eine Klasse oder ein Objekt haben und wissen möchten, ob Sie eine bestimmte Methode aufrufen können, verwenden Sie can(). Wickeln Sie es in einem eval-Block so kann() aufrufen können auf Dinge, die nicht einmal Objekte sind immer noch zurück falsch zu bekommen, statt des Todes, in diesen Fällen:
if(eval { $object->can('method_name') })
{
$object->(@args);
}
Ich werde nur diese lassen sich hier für wenn ich es vergesse. Das ist extrem mächtig; Schade, dass es so aus dem Weg ist, dass die meisten Perl-Programmierer es nie erfahren.
package Foo;
use strict;
sub foo1 {};
sub foo2 {};
our $foo3 = sub{};
my $foo4 = "hello, world!";
package Bar;
use strict;
# woo, we're javascript!
(sub {
*Bar::foo1 = sub { print "hi!"; };
*Bar::foo2 = sub { print "hello!"; };
$Bar::foo1 = 200;
})->();
package main;
use strict;
use Data::Dumper;
$Data::Dumper::Deparse = 1;
print Dumper \%Data::Dumper::;
print Dumper \%Foo::;
print Dumper \%Bar::;
- 1. Wie durchlaufen Sie alle Eigenschaften einer Klasse?
- 2. Wie kann ich in Perl mehrere Listen gleichzeitig durchlaufen?
- 3. Wie kann ich alle Teilmengen einer Liste in Perl generieren?
- 4. Wie kann ich Methoden aus einer Klasse in Ruby aufrufen?
- 5. Methode einer Klasse überschreibt alle Methoden einer anderen Klasse
- 6. Kann ich (öffentliche) Attribute einer C++ - Klasse durchlaufen?
- 7. Wie kann ich alle Modelle in meiner Rails-App durchlaufen?
- 8. Wie kann ich alle Kontrollkästchen in einem Formular durchlaufen?
- 9. Wie kann ich alle Methoden in einem Protokoll bekommen?
- 10. Wie kann ich Introspektion in Perl durchführen?
- 11. Wie finde ich Methoden mit einer Annotation in einer Klasse?
- 12. Wie alle verfügbaren Methoden einer Klasse (Java) anzuzeigen
- 13. Wie kann ich alle Elemente meiner NSOutlineView durchlaufen?
- 14. Wie kann ich einen IP-Adressbereich durchlaufen?
- 15. Wie kann ich durch alle Spalten des OracleDataReader durchlaufen
- 16. Wie Methoden in einer Klasse aufrufen?
- 17. Wie kann ich Dateinamen in Stata durchlaufen
- 18. Wie sehe ich alle verfügbaren Methoden in einer SVC-Datei?
- 19. Wie mache ich 2 vergleichbare Methoden in nur einer Klasse?
- 20. Wie kann ich eine MySQL-Ergebnismenge durchlaufen?
- 21. Wie kann ich automatisch alle skalaren Variablen in Perl initialisieren?
- 22. Wie kann ich alle Leerzeichen und Zeilenumbrüche in Perl entfernen?
- 23. Wie kann ich alle Permutationen eines Arrays in Perl generieren?
- 24. Wie kann ich alle Subs in einem Perl-Paket exportieren?
- 25. erhalten Sie alle Methoden einer Objective-C-Klasse oder Instanz?
- 26. Wie mache ich statische Methoden in einer Klasse mit easymock?
- 27. Wie kann ich alle #Regionen und Methoden in C# reduzieren?
- 28. Durchlaufen Attribute mit DOM-Methoden?
- 29. Wie durchlaufen Sie alle Zeichen in einer Zeichenfolge?
- 30. Wie alle Methoden in XCode zu reduzieren?
Für die erste Frage finden Sie unter: http://stackoverflow.com/questions/910430/how-do-i-list-available-methods-on-a-given-object-or-package-in -perl – molf