2009-05-26 20 views

Respuesta

20

Si usted tiene un paquete llamado Foo, esto debe hacerlo:

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

Alternativamente, para obtener una lista de todos los métodos:

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

Debe recurrir a las matrices @ISA también – Beano

+0

Probar esto en XML :: Simple, Scalar :: Util y Exporter muestra todos los métodos que se exportan explícitamente. No obstante, recurrir a @ISA no debería ser tan difícil. –

+3

Por supuesto, tendrá dificultades para encontrar métodos de carga automática. – innaM

35

Hay (y no demasiado) muchos aspectos a haz esto en Perl porque hay muchas maneras de hacer las cosas en Perl. Como alguien comentó, los métodos automáticos siempre serán un poco complicados. Sin embargo, en lugar de plantear su propio enfoque, le sugiero que eche un vistazo al Class::Inspector en CPAN. Que le permitirá hacer algo como:

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

Finalmente he incluido Classline :: Inspector en línea en mi script de un solo archivo, esa es en realidad la solución más simple. Gracias. –

+2

Tenga en cuenta que Class :: Inspector tiene limitaciones. Puede ver los métodos definidos, pero no maneja nada en UNIVERSAL. –

+2

No es que la respuesta aceptada maneje UNIVERSAL tampoco ... – ephemient

12

si tiene un paquete que está utilizando Moose su razonablemente simple:

print PackageNameHere->meta->dump; 

Y para los datos más completa:

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

obtendrá tú empezaste. Para todo lo demás, los theres los métodos que aparecen en ->meta que se documentan en Class::MOP::Class

Puede hacer un poco de AdHoc falsificación de la bondad alces paquetes sin él con:

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

y luego proceder a utilizar el Class :: MOP métodos como lo harías con Moose.

Para empezar:

$meta->get_method_map(); 

uso alces; #, es impresionante.

+1

initialize devolverá la metaclase si está almacenada en la memoria caché, no es necesario verificarla manualmente, consulte por ejemplo las implementaciones para todo el azúcar en Moose.pm – perigrin

+1

Hmm y con una mayor investigación, parece que estoy en lo cierto y lo que está mal. Class :: MOP :: class_of() manejará las instancias y los nombres de las clases, mientras que la función que inicializa usa (Class :: MOP :: get_metaclass_by_name()) * only * maneja los nombres de las clases. – perigrin

+0

Kent - esto no funciona para mí - tal vez algo ha cambiado en el mundo de Moose. Tengo una esencia aquí: https://gist.github.com/rjattrill/6119205 –

4

En general, no puede hacer esto con un lenguaje dinámico como Perl. El paquete puede definir algunos métodos que puede encontrar, pero también puede crear métodos sobre la marcha que no tienen definiciones hasta que los use. Además, incluso llamar a un método (que funciona) podría no definirlo. Ese es el tipo de cosas que hacen que los lenguajes dinámicos sean agradables. :)

¿Qué tarea estás tratando de resolver?

Cuestiones relacionadas