2010-01-19 7 views
28

Come posso trovare il tipo di oggetto con cui sto trattando in Perl? Ho provato a usare perl -d per entrare nel debugger, ma non sono sicuro di cosa fare allora. Allo stesso modo mi piacerebbe un modo per vedere facilmente quali metodi sono disponibili per ogni oggetto, come può essere fatto?Come trovare il tipo di oggetto che ho su Perl?

+2

Correlato: http://stackoverflow.com/questions/460676/how-do-i-determine-if-an-object-implements-a-method-in-perl –

+0

Stavo cercando di eseguire il debug di uno script che itera attraverso una serie di oggetti, un sacco di volte con Perl trovo che non so quali metodi sono disponibili per quali oggetti, quindi stavo cercando un modo semplice per scoprirlo. – John

risposta

27

Il modo standard per dire quale tipo di oggetto si possiede è ref o Scalar::Util::blessed. Se tu conosci l'oggetto è benedetto, quindi restituiscono le stesse informazioni.

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

Ma ref sarà anche tornare 'hash' per gli hash unblessed, mentre blessed rifiuta di giocare a quel gioco.

Come per un elenco di metodi, per lo stile di puntatore benedetto dell'oggetto perl, è abbastanza facile codificarne uno da soli. Il codice qui sotto funziona abbastanza bene per me. Restituisce i nomi delle funzioni (quelle che prendono lo "slot CODE" del nome specificato) mappate sul pacchetto che le definisce.

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; 
} 
  • Questo funziona per gli oggetti ragionevolmente complessi pure, ma se il pacchetto possessore contiene un sacco di codice generato, non sta andando essere che utile sapere quale pacchetto i generatori bloccati il ​​puntatore del codice Significa più per trovare quale pacchetto ha generato il codice.

  • Stando così le cose, si potrebbe ottenere il codice di esecuzione codice, tra cui Data::Dumper e l'impostazione $Data::Dumper::Deparse-1, in questo modo: (local $Data::Dumper::Deparse = 1;) e poi scaricare il puntatore del codice, in questo modo: say Dumper($code_ref);

  • NON funziona per metodi validi che devono ancora essere creati con qualsiasi metodo AUTOLOAD. Se vedi quelli nella lista, l'oggetto potrebbe fare di più, ma quello che fa, non lo sai.

  • La "classe base" UNIVERSAL è inclusa, poiché tale classe contiene comportamenti utilizzabili dall'oggetto.

Buona fortuna.

5

La funzione blessed da Scalar::Util vi dirà il nome del pacchetto di qualsiasi riferimento beati (un oggetto.)

per scoprire quali sono disponibili metodi, consultare la documentazione per quel pacchetto. In alternativa, puoi usare qualcosa come Class::MOP::Class per creare un'istanza di un metaclasse e ottenere informazioni introspettive sui metodi che contiene.

3

Solo per completezza, ecco una breve introduzione al debugger.

perl -d your_program 

avvia sotto il bugger. Otterrai il controllo sulla prima riga eseguibile (le istruzioni sull'uso e simili sono già state eseguite a questo punto).

's' passerà alla riga successiva. Una volta che hai inserito un 's', puoi semplicemente premere return per ripeterlo. 's' si ridurrà a funzioni/subroutine/metodi. O continuare a camminare fino a tornare o immettere il comando 'r' per eseguire il resto della funzione e tornare a destra dopo la chiamata.

Se si desidera eseguire le sottoprogrammate 'over', cioè eseguirle e tornare senza dover eseguire il comando e tornare, utilizzare 'n. Il ritorno a capo dopo il primo 'n' continua anche a fare 'n' per te.

Se si conosce la linea in cui si desidera interrompere, utilizzare il comando 'b' - b numero di telefono - per impostare un punto di interruzione, quindi 'c' per continuare finché non lo si raggiunge. Nota che ogni volta che ti "c" e torni al punto di interruzione, ti fermerai di nuovo. Utilizzare 'B linenumber' per disattivare il breakpoint.

Quindi supponiamo che hai ottenuto a qualcosa di simile:

my $obj = complex_function_returning_unknown_thing; 

Il debugger è solo voi indicata questa linea, che dice: "Non ho ancora eseguita questa, ma è quello che farò dopo. " Immettere 'n' per eseguire la subroutine, quindi utilizzare il comando 'x' per esaminare l'oggetto: 'x $ obj'. Se è grande, puoi dire '| x $ obj' che esegue l'output attraverso un cercapersone. Per vedere quali metodi ha l'oggetto, usa 'm $ obj'.

C'è molto di più nel debugger, ma puoi effettivamente usarlo per questo genere di cose - devi semplicemente vedere il tipo di oggetto che stai ricevendo da un codice e scoprire quali metodi l'oggetto hai ha.

Potrebbe essere più utile a 'x' l'oggetto, e poi andare a vedere la fonte della classe dell'oggetto è stato benedetto in per scoprire che cosa si dovrebbe fare al contrario di ciò che si può fare. Il comando 'x' è praticamente 'print ref ($ obj)' incrociato comunque con Data :: Dumper.

Problemi correlati