Какой лучший способ обнаружить все подпрограммы, которые есть в модуле Perl? - PullRequest
24 голосов
/ 03 марта 2009

Какой лучший способ программно обнаружить все подпрограммы, которые есть в модуле perl? Это может быть модуль, класс (без @EXPORT) или что-то промежуточное.

Edit: все методы ниже, похоже, они будут работать. Я бы, вероятно, использовал Class :: Sniff или Class :: Inspector в производстве. Тем не менее, ответ Леона помечен как «принятый», так как он отвечает на поставленный вопрос, хотя должен использоваться no strict 'refs'. :-) Class :: Sniff может быть хорошим выбором по мере продвижения; Похоже, много мыслей ушло на это.

Ответы [ 3 ]

22 голосов
/ 03 марта 2009
sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}

ETA: если вы хотите отфильтровать импортированные подпрограммы, вы можете сделать это

use B qw/svref_2object/;

sub in_package {
    my ($coderef, $package) = @_;
    my $cv = svref_2object($coderef);
    return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL');
    return $cv->GV->STASH->NAME eq $package;
}

sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"}
}
12 голосов
/ 03 марта 2009

Класс :: Инспектор

Class :: Inspector позволяет получить информацию о загруженном классе. Большую часть или всю эту информацию можно найти другими способами, но они не всегда очень дружелюбны и обычно включают относительно высокий уровень волшебства Perl или странный и необычно выглядящий код. Class :: Inspector пытается предоставить более простой и дружественный интерфейс для этой информации ...

9 голосов
/ 03 марта 2009

Посмотрите на это: Класс :: Sniff

Интерфейс в настоящий момент достаточно временен и может измениться. После создания нового экземпляра вызов метода report - ваш лучший вариант. Затем вы можете визуально проверить его на наличие потенциальных проблем:

my $sniff = Class::Sniff->new({class => 'Some::Class'});
print $sniff->report;

Этот модуль пытается помочь программистам найти «запахи кода» в объектно-ориентированном коде. Если он что-то сообщает, это не значит, что ваш код неверен. Это просто означает, что вы, возможно, захотите взглянуть на свой код более внимательно, чтобы увидеть, есть ли у вас какие-либо проблемы.

В настоящее время мы предполагаем, что Perl по умолчанию расположен в крайнем левом порядке поиска в глубину. Мы можем изменить это в будущем (и есть обходной путь с методом путей. Подробнее об этом позже) ...

...