2009-05-26 4 views

Répondre

20

Si vous avez un paquet appelé Foo, cela devrait le faire:

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'; 

Sinon, pour obtenir une liste de toutes les méthodes:

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

Doit récursivité des baies @ISA ainsi – Beano

+0

Test sur XML :: Simple, Scalar :: Util et Exporter montre toutes les méthodes explicitement exportées. Récursif @ISA ne devrait pas être si difficile, cependant. –

+3

Bien sûr, vous aurez du mal à trouver des méthodes chargées automatiquement. – innaM

35

Il y a (un peu trop) de nombreuses façons de Faites cela en Perl parce qu'il y a tellement de façons de faire les choses en Perl. Comme quelqu'un l'a commenté, les méthodes chargées automatiquement seront toujours un peu compliquées. Cependant, plutôt que de lancer votre propre approche, je vous suggère de jeter un coup d'œil sur le CPAN au Class::Inspector. Cela vous permettra de faire quelque chose comme:

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

J'ai finalement inclus dans mon script un fichier Class :: Inspector en ligne, c'est en fait la solution la plus simple. Merci. –

+2

Notez que Class :: Inspector a des limitations. Il peut voir les méthodes définies, mais ne gère rien dans UNIVERSAL. –

+2

Ce n'est pas comme la réponse acceptée gère UNIVERSAL soit ... – ephemient

12

si vous avez un paquet qui utilise Moose son assez simple:

print PackageNameHere->meta->dump; 

Et pour les données plus complète:

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

obtiendrai vous avez commencé. Pour tout le reste, theres les méthodes qui apparaissent sur ->meta qui sont documentés dans Class::MOP::Class

Vous pouvez faire un peu de AdHoc trucage de bonté à l'orignal pour les paquets sans avec:

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

et passer ensuite à utiliser la Class :: MOP méthodes comme vous le feriez avec Moose.

Pour commencer:

$meta->get_method_map(); 

utilisation Moose; #, son impressionnant.

+1

initialize retourne la métaclasse si elle est en cache, pas besoin de vérifier manuellement, voir par exemple les implémentations pour tout le sucre dans Moose.pm – perigrin

+1

Hmm et avec une enquête plus approfondie, je semble être à la fois vrai et faux. Class :: MOP :: class_of() gère les instances ainsi que les noms de classe, tandis que la fonction qui initialise utilise (Class :: MOP :: get_metaclass_by_name()) * seulement * gère les noms de classe. – perigrin

+0

Kent - cela ne fonctionne pas pour moi - peut-être que quelque chose a changé dans le monde Moose. J'ai un aperçu ici: https://gist.github.com/rjattrill/6119205 –

4

En général, vous ne pouvez pas le faire avec un langage dynamique comme Perl. Le paquet peut définir certaines méthodes que vous pouvez trouver, mais il peut également créer des méthodes à la volée qui n'ont pas de définitions jusqu'à ce que vous les utilisiez. De plus, même l'appel d'une méthode (qui fonctionne) peut ne pas le définir. C'est le genre de choses qui rendent les langages dynamiques agréables. :)

Quelle tâche tentez-vous de résoudre?

Questions connexes