Использование eval для загрузки модулей - PullRequest
2 голосов
/ 28 июля 2011

У меня проблемы с Perl и встроенной функцией eval. Я посмотрел в Интернете, но не могу найти ответ или образец кода.

Я бы хотел загружать модули динамически (я не знаю их раньше времени выполнения)

$module_name="Auth_Auth_Test";
my $ret1;
ret = eval{
     "use ".$module_name;
     $ret1 = $module_name."::test(".$log.")";
};              
$log->debug ($@) if $@;
$log->debug ("Ret".$ret1);

Возвращение было:

RetAuth_Auth_Test :: тест (на заказ :: Вход = HASH (0x1194468))

У меня сработал следующий метод, но я не могу загрузить более одного модуля с одной и той же подпрограммой:

my $use = "use ".$module_name." qw(&test)";
$ret = eval $use;

# Debug for eval
$log->debug ($@) if $@;

$ret = test($log);

Спасибо за любую помощь

Ответы [ 3 ]

4 голосов
/ 28 июля 2011

Используйте Module :: Load вместо.

2 голосов
/ 10 января 2013

Я настоятельно советую вам использовать Class :: Load , это повсеместно в настоящее время из-за зависимости от Moose:

use Class::Load qw(:all);

my $module = 'Web::Spider::' . $module;
try_load_class($module)
    or warn "unable to load '$module'";

А вот обширное объяснение того, почему это лучшечем Module :: Load (несмотря на то, что в последнее время он был частью ядра Perl): http://blog.fox.geek.nz/2010/11/searching-design-spec-for-ultimate.html

TL; DR:

Причуда того, как функционирует Perl 5.8 (что теперь решаетсяв 5.10) то, что, как только модуль требуется, пока этот файл существует на диске, $ INC {} будет обновляться, чтобы сопоставить имя модуля с найденным именем файла.Это не кажется плохим, пока вы не увидите, как оно ведет себя по отношению к тому, что вызывается снова где-то еще.

Class :: Load решает это.Module :: Load not.

1 голос
/ 28 июля 2011

В первом фрагменте

"use ".$module_name;

просто оценивается как строка.Это потому, что разница между строкой eval и блоком eval.См. eval документацию для различий между ними.

Вы можете использовать что-то вроде этого:

use strict; use warnings;

my $module_name = "Auth_Auth_Test";
eval "require $module_name";
if($@) {
    warn "Could not load module: $@\n";
}
my $ret = $module_name->test("params");
print "return $ret\n";

Но в любом случае, предложение Даксима звучит правильно, вы, вероятно, не хотитеизобретать что-то уже распространенное с помощью Perl. Module :: Load находится в ядре с 5.9.4.

...