2009-05-26 1 views

risposta

20

Se si dispone di un pacchetto chiamato Foo, questo dovrebbe farlo:

no strict 'refs'; 
for(keys %Foo::) { # All the symbols in Foo's symbol table 
    print "$_\n" if exists &{"Foo::$_"}; # check if symbol is method 
} 
use strict 'refs'; 

In alternativa, per ottenere una lista di tutti i metodi:

no strict 'refs'; 
my @methods = grep { defined &{$_} } keys %Foo::; 
use strict 'refs'; 
+3

In caso di recesso degli array @ISA e – Beano

+0

Test su XML :: Simple, Scalar :: Util ed Exporter mostra tutti i metodi che vengono esportati in modo esplicito. La ricorsione su @ISA non dovrebbe essere così difficile, però. –

+3

Naturalmente, sarà difficile trovare metodi autoloaded. – innaM

35

Ci sono (un po 'troppo) molti modi per fallo in Perl perché ci sono tanti modi per fare cose in Perl. Come qualcuno ha commentato, i metodi di caricamento automatico saranno sempre un po 'complicati. Tuttavia, anziché seguire il tuo approccio, ti suggerisco di dare un'occhiata a Class::Inspector su CPAN. Che vi permetterà di fare qualcosa di simile:

my @methods = Class::Inspector->methods('Foo::Class', 'full', 'public'); 
+2

Ho finalmente incluso inline Class :: Inspector nel mio script a un file, che è in realtà la soluzione più semplice. Grazie. –

+2

Nota che Class :: Inspector ha limitazioni. Può vedere i metodi definiti, ma non gestisce nulla in UNIVERSAL. –

+2

Non è come le maniglie di risposta accettate UNIVERSAL o ... – ephemient

12

se si dispone di un pacchetto che utilizza Moose sua ragionevolmente semplice:

print PackageNameHere->meta->dump; 

E per i dati più completa:

use Data::Dumper; 
print Dumper(PackageNameHere->meta); 

andranno hai iniziato tu. Per tutto il resto, theres i metodi che appaiono sul ->meta documentate nel Class::MOP::Class

Si può fare un po 'di AdHoc falsificazione della bontà alce per i pacchetti senza di essa con:

use Class::MOP::Class; 
my $meta = Class::MOP::Class->initialize(PackageNameHere); 

e quindi procedere ad utilizzare la Class :: Metodi MOP come faresti con Moose.

Per cominciare:

$meta->get_method_map(); 

uso Moose; #, è impressionante.

+1

initialize restituirà il metaclass se è memorizzato nella cache, non è necessario verificarlo manualmente, vedere ad esempio le implementazioni per tutto lo zucchero in Moose.pm – perigrin

+1

Hmm e con ulteriori indagini mi sembra sia giusto che sbagliato. Class :: MOP :: class_of() gestisce sia le istanze che i nomi delle classi, mentre la funzione che inizializza utilizza (Class :: MOP :: get_metaclass_by_name()) * only * gestisce i nomi delle classi. – perigrin

+0

Kent - questo non funziona per me - forse qualcosa è cambiato nel mondo Moose. Ho un senso qui: https://gist.github.com/rjattrill/6119205 –

4

In generale, non è possibile farlo con un linguaggio dinamico come Perl. Il pacchetto potrebbe definire alcuni metodi che puoi trovare, ma può anche inventare metodi che non hanno definizioni finché non li usi. Inoltre, anche chiamando un metodo (che funziona) potrebbe non definirlo. Questo è il tipo di cose che rendono i linguaggi dinamici piacevoli. :)

Quale compito stai cercando di risolvere?