¿Cómo se repiten todos los métodos de una clase en Perl? ¿Hay alguna buena referencia en línea para la introspección o reflexión de Perl?¿Cómo repito todos los métodos de una clase en Perl?
Respuesta
La recomendación que dio Todd Gardner para usar Moose es buena, pero el código de ejemplo que eligió no es muy útil.
Si está inspeccionando un no alces usando la clase, usted haría algo como esto:
use Some::Class;
use Class::MOP;
my $meta = Class::MOP::Class->initialize('Some::Class');
for my $meth ($meta->get_all_methods) {
print $meth->fully_qualified_name, "\n";
}
Véase el Class::MOP::Class docs para más detalles sobre cómo hacer introspección.
También notará que utilicé Class :: MOP en lugar de Moose. Class :: MOP (MOP = Meta-Object Protocol) es la base sobre la cual Moose construye. Si trabajas con clases que no son de Moose, usar Moose para introspect no te gana nada.
Si desea, puede use Moose()
y Moose::Meta::Class->initialize
en lugar de CMOP.
+1: Eso está bien, no sabía que podrías usar Class :: MOP así. –
Explicaré las limitaciones de esto en mi respuesta. Incluso con una clase vacía no puede recoger los métodos de UNIVERSAL, y no puede recoger ninguno de AUTOLOAD. –
@brian d foy: Usar AUTOLOAD es malo, mmmkay? – HoldOffHunger
Depende si quiere decir, cualquier clase, o si estaba implementando la suya propia. Para este último, utilizo Moose, que ofrece una sintaxis muy clara para estas características. Del libro de cocina:
my %attributes = %{ $self->meta->get_attribute_map };
for my $name (sort keys %attributes) {
my $attribute = $attributes{$name};
if ( $attribute->does('MyApp::Meta::Attribute::Trait::Labeled')
# ... keeps on
Tenga en cuenta que Moose no encontrará ningún atributo a menos que la clase que está introspectando se definió utilizando Moose en primer lugar. Sin embargo, la introspección del método, así como la mayoría de los demás bits, funcionará bien. –
En el caso general, tendrá que inspeccionar la tabla de símbolos (a menos que use Moose). Por ejemplo, para una lista de los métodos definidos en el paquete IO::File
:
use IO::File;
no strict 'refs';
print join ', ', grep { defined &{"IO::File::$_"} } keys %{IO::File::};
El hash %{IO::File::}
es la tabla de símbolos del IO::File package
y la grep
los filtros a cabo entradas no subrutina (por ejemplo, variables de paquete).
Para extender esto y que incluya métodos heredados, debe buscar de forma recursiva las tablas de símbolos de las clases principales (@IO::File::ISA
).
Aquí es un ejemplo completo:
sub list_methods_for_class {
my $class = shift;
eval "require $class";
no strict 'refs';
my @methods = grep { defined &{$class . "::$_"} } keys %{$class . "::"};
push @methods, list_methods_for_class($_) foreach @{$class . "::ISA"};
return @methods;
}
Para obtener más información sobre los paquetes y tablas de símbolos, ver la página perlmod hombre.
No todos los métodos tienen que definirse en la tabla de símbolos, y te falta UNIVERSAL. –
Me preguntaba si alguna de las soluciones para esta pregunta, especialmente esta aquí, genera una nueva instancia de objeto cada vez que se llama al código y si se recicla o cada instancia permanece en la memoria hasta que finaliza el programa. Debido a que el uso de la reflexión/introspección en algunos otros lenguajes como .NET y Java, debe tener cuidado en dónde instanciar la referencia del objeto de clase, sino que puede obtener nuevas instancias por llamada. – David
Probablemente desee Class :: Inspector-> methods ('Your :: Class').
Nuff dijo.
Puede obtener fácilmente una lista de los métodos definidos de una clase utilizando las respuestas ya proporcionadas. Sin embargo, Perl es un lenguaje dinámico, lo que significa que más métodos se pueden definir más adelante. Realmente no hay una forma de obtener una lista de todos los métodos a los que se encargará una clase en particular. Para obtener más detalles sobre este tipo de cosas, tengo algunos capítulos en Mastering Perl.
Las personas te dan (y suben) respuestas sin decirte las limitaciones.
Adam menciona su Class::Inspector, pero realmente no funciona porque está tratando de hacer algo que un lenguaje dinámico no hace (y eso es estático :) Por ejemplo, aquí hay un fragmento donde Class :: Inspector no devuelve ningún método , pero todavía puedo llamar a la VERSION
método (así como isa
y can
):
BEGIN {
package Foo;
our $VERSION = '1.23'
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports nothing
print Foo->VERSION, "\n";
Aquí hay otro caso en el que puedo llamar a cualquier método que me gusta, pero Clase :: inspector sólo devuelve AUTOLOAD
(y todavía falta VERSION
, isa
y can
):
BEGIN {
package Foo;
our $VERSION = '1.23';
my $object = bless {}, __PACKAGE__;
sub AUTOLOAD { $object }
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports only "AUTOLOAD"
print Foo->dog->cat->bird, "\n";
Curiosamente, todo el mundo parece ignorar UNIVERSAL, probablemente porque no lo manejan explícitamente, ya que es prácticamente solo en @ISA. Puedo añadir un método debug
a cada clase, y la clase :: inspector sigue sin ver que a pesar de que se trata de un método definido:
BEGIN {
sub UNIVERSAL::debug { "Hello debugger!\n" }
package Foo;
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # still reports nothing
print Foo->debug, "\n";
Class::MOP tiene las mismas limitaciones.
No todos los módulos van a utilizar AUTOLOAD, pero tampoco es una característica oscura o rara. Si no te importa que te pierdas algunos de los métodos, Class :: Inspector o Class :: MOP podrían estar bien. Simplemente no le dará una lista de todos los métodos que puede invocar en una clase o un objeto en todos los casos.
Si tiene una clase o un objeto y desea saber si puede llamar a un método en particular, use can(). Envolverlo en un bloque eval por lo que puede puede llamar puede() en cosas que no son incluso objetos que todavía volver falsa, en lugar de la muerte, en esos casos:
if(eval { $object->can('method_name') })
{
$object->(@args);
}
Voy a dejar esto aquí para cuando lo olvido Esto es extremadamente poderoso; Es una pena que la mayoría de los programadores de Perl nunca lo experimenten.
package Foo;
use strict;
sub foo1 {};
sub foo2 {};
our $foo3 = sub{};
my $foo4 = "hello, world!";
package Bar;
use strict;
# woo, we're javascript!
(sub {
*Bar::foo1 = sub { print "hi!"; };
*Bar::foo2 = sub { print "hello!"; };
$Bar::foo1 = 200;
})->();
package main;
use strict;
use Data::Dumper;
$Data::Dumper::Deparse = 1;
print Dumper \%Data::Dumper::;
print Dumper \%Foo::;
print Dumper \%Bar::;
- 1. ¿Cómo dividir todos los métodos de una clase en GDB?
- 2. cómo mantener todos los métodos en una clase con ProGuard
- 3. ¿Cómo puedo redefinir los métodos de clase Perl?
- 4. ¿Puedo obtener todos los métodos de una clase?
- 5. Clase abstracta con todos los métodos concretos
- 6. ¿Cómo colapsar todos los métodos en XCode?
- 7. ¿Existe alguna manera de conocer los métodos de una instancia de una clase desconocida en Perl
- 8. Listar todos los métodos de una clase dada, excluyendo los métodos de la clase padre en PHP
- 9. Poner todos los métodos en la definición de clase
- 10. registrar todos los métodos?
- 11. Cómo imprimir todos los valores de una matriz en Perl
- 12. ¿Todos los métodos en la clase principal deben ser estáticos?
- 13. ¿Cómo puedo averiguar todos los métodos definidos para una clase en R?
- 14. ¿Cómo manejo los errores en cadenas de métodos en Perl?
- 15. ¿Cómo repito un carácter n veces en una cadena?
- 16. ¿Cómo puedo obtener todos los métodos en un protocolo?
- 17. Agregue un punto de interrupción de método a todos los métodos de una clase en EclipseIDE
- 18. En .NET, ¿puedes usar el reflejo para obtener todos los métodos no heredados de una clase?
- 19. ¿Imprimir todos los nombres de métodos de una clase en Ruby?
- 20. Obtener solo los métodos declarados de una clase en PHP
- 21. ¿Cómo creo una clase Perl?
- 22. copie todos los nombres de métodos - Intellij
- 23. Ruby - ¿Cómo redefinir los métodos de clase?
- 24. ¿Todos los métodos devuelven `this` a monad?
- 25. Redefina los métodos de clase o clase
- 26. ¿Cómo enumerar los métodos de clase en gdb?
- 27. ¿Cómo extiendo una clase con los métodos de extensión C#?
- 28. ¿Cómo puedo documentar los métodos concisamente en el código Perl?
- 29. obtener todos los métodos de una clase o instancia objetivo-c?
- 30. ¿Por qué tienen todos los métodos/variables estáticos en una clase no estática?
Por primera cuestión, véase: http://stackoverflow.com/questions/910430/how-do-i-list-available-methods-on-a-given-object-or-package-in -perl – molf