2010-01-19 6 views
28

Wie finde ich heraus, um welchen Objekttyp es sich in Perl handelt? Ich versuchte per Perl -d den Debugger zu betreten, aber ich bin mir nicht sicher, was ich dann tun soll. Ebenso möchte ich einen Weg, um leicht zu sehen, welche Methoden für jedes Objekt verfügbar sind, wie kann das gemacht werden?Wie finde ich welchen Objekttyp in Perl?

+2

Related: http://StackOverflow.com/Questions/460676/How-Do-I-Determine-if-an-Objekt-Implements-Amethod-in-Perl –

+0

Ich habe versucht, ein Skript zu debuggen durch Iterieren ein Array von Objekten, die meiste Zeit mit Perl Ich weiß nicht, welche Methoden für welche Objekte verfügbar sind, also suchte ich nach einem einfachen Weg, das herauszufinden. – John

Antwort

27

Die Standardmethode, um anzugeben, welche Art von Objekt Sie haben, ist entweder ref oder Scalar::Util::blessed. Wenn Sie wissen das Objekt ist gesegnet, dann geben sie die gleiche Information zurück.

my $class1 = blessed($obj); 
my $class2 = ref $obj; 

Aber ref kehrt auch 'HASH' für unblessed Hashes, während blessed das Spiel zu spielen weigert.

Wie für eine Liste von Methoden, für den gesegneten Zeiger-Stil von Perl-Objekt, ist es einfach genug, um sich selbst zu programmieren. Der folgende Code funktioniert ziemlich gut für mich. Es gibt die Namen von Funktionen zurück (die den "CODE-Slot" des gegebenen Namens annehmen), die dem Paket zugeordnet sind, das sie definiert.

sub class_methods { 
    use Class::ISA; 
    my $obj = shift; 
    return unless ref($obj); 
    my %meth_names; 
    foreach my $anc (Class::ISA::self_and_super_path(ref $obj), 'UNIVERSAL') { 
     my $stash = \%{"$anc\::"}; 
     my @funcs 
      = grep { m/^[_\p{Alpha}]/    # begins with _ or alpha 
        && !exists $meth_names{$_}  # no clobbering 
        && defined *{$stash->{$_}}{CODE} # has a filled CODE slot 
        } keys %$stash 
      ; 
     # assign to the "hash slice", keyed by all the entries in @funcs 
     # the value of $anc repeated as many times as elements in @funcs. 
     @meth_names{@funcs} = ($anc) x @funcs; 
    } 
    return %meth_names; 
} 
  • Dies wird auch für einigermaßen komplexen Objekten arbeiten, aber wenn der besitzende Paket eine Menge generierten Code enthält, ist es nicht so hilfreich sein würde zu wissen, welches Paket die Generatoren den Code Zeiger stecken in Es wird mehr bedeuten zu finden, welches Paket den Code generiert hat.

  • dies der Fall ist, Sie könnte den Code aus laufenden Code erhalten, einschließlich Data::Dumper und $Data::Dumper::Deparse-1, wie Einstellung so: (local $Data::Dumper::Deparse = 1;) und dann den Code Pointer Dumping, etwa so: say Dumper($code_ref);

  • Es wird nicht arbeiten für gültige Methoden, die noch von AUTOLOAD Methoden erstellt werden müssen. Wenn Sie diese in der Liste sehen, könnte das Objekt mehr tun, aber was es alles tut, wissen Sie nicht.

  • Die "Basisklasse" UNIVERSAL ist enthalten, da diese Klasse das vom Objekt verwendbare Verhalten enthält.

Viel Glück.

5

Die blessed Funktion von Scalar::Util werden Ihnen sagen, die Paketnamen einer gesegneten Referenz (ein Objekt).

Um herauszufinden, welche Methoden zur Verfügung stehen, finden Sie in die Dokumentation für das Paket. Alternativ können Sie eine Instanz wie etwa Class::MOP::Class verwenden, um eine Metaklasse zu instanziieren und introspektive Informationen über die darin enthaltenen Methoden zu erhalten.

3

Nur der Vollständigkeit halber, hier ist eine sehr kurze Einführung in den Debugger.

perl -d your_program 

startet es unter dem Bugger. Sie erhalten die Kontrolle über die erste ausführbare Zeile (use-Anweisungen und Ähnliches wurden bereits an dieser Stelle ausgeführt).

's' wird in die nächste Zeile wechseln. Sobald Sie ein 's' eingegeben haben, können Sie einfach Return drücken, um es zu wiederholen. 's' wird in Funktionen/Subroutinen/Methoden verzweigen. Gehen Sie entweder weiter, bis Sie zurückkehren, oder geben Sie den Befehl 'r' ein, um den Rest der Funktion auszuführen und nach dem Anruf wieder nach rechts zurückzukehren.

Wenn Sie "über" Subroutinen gehen wollen - dh sie ausführen und zurückkehren, ohne dass Sie einsteigen und zurückkehren müssen, verwenden Sie 'n. Der Wagenrücklauf nach dem ersten 'n' macht auch immer 'n' für dich.

Wenn Sie die Zeile kennen, in der Sie anhalten möchten, verwenden Sie den Befehl 'b' - b linenumber -, um einen Haltepunkt festzulegen, und dann 'c', bis Sie ihn erreichen. Beachte, dass du jedes Mal, wenn du "c" kommst und zum Haltepunkt zurückkehrst, wieder anhalten wirst. Verwenden Sie "B linenumber", um den Haltepunkt wieder zu deaktivieren.

Also lassen Sie uns annehmen, dass Sie so etwas wie diese bekommen haben:

my $obj = complex_function_returning_unknown_thing; 

ist der Debugger nur Ihnen gezeigt, diese Linie, die das sagt „nicht ausgeführt noch habe ich, aber es ist das, was ich als nächstes tun wird. " Geben Sie 'n' ein, um die Subroutine auszuführen, und verwenden Sie dann den Befehl 'x', um das Objekt zu betrachten: 'x $ obj'. Wenn es groß ist, können Sie '| x $ obj' sagen, das die Ausgabe über einen Pager ausführt. Um zu sehen, welche Methoden das Objekt hat, verwenden Sie 'm $ obj'.

Es gibt viel mehr zum Debugger, aber Sie können es tatsächlich für diese Art von Sache verwenden - Sie müssen einfach den Typ eines Objekts sehen, das Sie von einem Code erhalten und herausfinden, welche Methoden das Objekt hat hat.

Es kann nützliche ‚x‘ das Objekt, und dann an der Quelle der Klasse aussehen geht das Objekt in gesegnet worden ist, was Sie , um herauszufinden, sollten im Gegensatz zu tun, was Sie tun können. Der Befehl 'x' ist ziemlich genau 'print ref ($ obj)', der sowieso mit Data :: Dumper gekreuzt wird.

Verwandte Themen