Подтвердить что ты не робот

Как определить, существует ли функция Perl во время выполнения?

Я работаю над тестовой платформой в Perl. В рамках тестов мне может потребоваться добавить предварительные условия или проверки условий для любого данного теста, но не обязательно для всех из них. То, что у меня есть, выглядит примерно так:

eval "&verify_precondition_TEST$n";
print [email protected] if [email protected];

К сожалению, это выводит "Undefined подпрограмма & ver_precondition_TEST1, вызываемая при...", если функция не существует.

Как я могу заранее определить, существует ли функция, прежде чем пытаться ее вызвать?

4b9b3361

Ответ 1

Определяется:

if (eval "defined(&verify_precondition_TEST$n)") {
    eval "&verify_precondition_TEST$n";
    print [email protected] if [email protected];
}
else {
    print "verify_precondition_TEST$n does not exist\n";
}

РЕДАКТИРОВАТЬ: Хмм, я думал об эволюции, как в вопросе, но с символическими ссылками, поднятыми с Леон Тиммерманом, не могли бы вы сделать

if (defined(&{"verify_precondition_TEST$n"}) {
    &{"verify_precondition_TEST$n"};
    print [email protected] if [email protected];
}
else {
    print "verify_precondition_TEST$n does not exist\n";
}

даже со строгим?

Ответ 2

Package::Name->can('function')

или

*Package::Name::function{CODE}

# or no strict; *{ "Package::Name::$function" }{CODE}

или просто жить с исключением. Если вы вызываете функцию в eval и [email protected], то вы не можете вызвать функцию.

Наконец, похоже, что вам может понадобиться Test:: Class вместо того, чтобы писать это самостоятельно.

Изменить: defined &function_name (или вариант no strict; defined &{ $function_name }), как указано в других ответах, выглядит наилучшим образом. UNIVERSAL:: can лучше всего подходит для чего-то, что вы собираетесь назвать методом (стилистически), и зачем беспокоиться о том, чтобы использовать таблицу символов, когда Perl дает вам синтаксис, чтобы делать то, что вы хотите.

Обучение ++:)

Ответ 3

sub function_exists {    
    no strict 'refs';
    my $funcname = shift;
    return \&{$funcname} if defined &{$funcname};
    return;
}

if (my $subref = function_exists("verify_precondition_TEST$n") {
    ...
}

Ответ 4

Я использовал Leon подход, но когда у меня было несколько пакетов, он не удался. Я точно не знаю, почему; Я думаю, что это связано с распространением сферы действия между пространствами имен. Это решение, с которым я столкнулся.

my %symbols = ();
my $package =__PACKAGE__; #bring it in at run-time
{
    no strict;
    %symbols = %{$package . "::"}; #See Symbol Tables on perlmod
}
print "$funcname not defined\n" if (! defined($symbols{$funcname});

Литература:
__ PACKAGE__ ссылка на странице perlmod.

Пакеты /__ PACKAGE__ ссылка на Perl Training Australia.