Вы можете легко получить список определенных методов класса, используя ответы, уже предоставленные. Тем не менее, Perl является динамическим языком, что означает, что другие методы могут быть определены позже. На самом деле нет способа получить список всех методов, с которыми будет работать какой-либо конкретный класс. Для более подробной информации о подобных вещах у меня есть несколько глав в Мастеринг Perl .
Люди дают вам (и голосуют против) ответы, не сообщая вам об ограничениях.
Адам упоминает о своем Class :: Inspector , но на самом деле это не работает, потому что он пытается сделать что-то, чего не делает динамический язык (и это будет статично :) Например, вот фрагмент где Class :: Inspector не возвращает методов, но я все еще могу вызвать метод VERSION
(а также isa
и 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";
Вот еще один случай, когда я могу вызвать любой метод, который мне нравится, но Class :: Inspector возвращает только AUTOLOAD
(и все еще отсутствует VERSION
, isa
и 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";
Любопытно, что все, кажется, игнорируют UNIVERSAL, возможно, потому, что они явно не обращаются с ним, потому что это только виртуально в @ISA. Я могу добавить метод debug
к каждому классу, и Class :: Inspector по-прежнему пропускает его, хотя это определенный метод:
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";
Класс :: MOP имеет те же ограничения.
Не каждый модуль будет использовать AUTOLOAD, но это не редкая и не редкая функция. Если вы не возражаете против того, что вы пропустите некоторые методы, тогда Class :: Inspector или Class :: MOP могут подойти. Это просто не даст вам список всех методов, которые вы можете вызывать для класса или объекта в каждом случае.
Если у вас есть класс или объект, и вы хотите знать, можете ли вы вызвать конкретный метод, используйте can (). Оберните его в блок eval, чтобы функция can могла вызывать can () для объектов, которые даже не являются объектами, и возвращают значение false, вместо смерти, в следующих случаях:
if( eval { $object->can( 'method_name' ) } )
{
$object->( @args );
}