Как мне динамически изменить путь к модулю Perl?

У меня есть две разные версии модуля Perl. В настоящее время критически важный сценарий использует версию модуля, заданную переменной среды, и система полагается на разные задачи, выполняемые разными пользователями. Среда пользователя будет определять, какая версия модуля Perl была использована.

Теперь я хотел бы изменить это на версию, указанную внутри сценария Perl, т.е. в зависимости от переданных параметров. К сожалению, такой код:

if ($new){ use lib "newdir"; }
else{ use lib "olddir"; }
use module;

не работает. Perl просто добавляет newdir, а затем olddir к @INC, а затем запускает сценарий.

Как мне динамически указать, какой модуль использовать?


person pythonic metaphor    schedule 01.02.2010    source источник


Ответы (3)


Вам нужно использовать блок BEGIN{}, чтобы ваш _2 _-_ 3_ код запускался во время компиляции:

BEGIN {
    if ($new) { unshift @INC, "newdir"; }
    else {      unshift @INC, "olddir"; }
}
use module;

Вы также можете установить переменную среды PERL5LIB, чтобы вам не пришлось выполнять такого рода конфигурация в скрипте.

person mob    schedule 01.02.2010
comment
Ваш странный стиль брекетинга оставил вам незакрытый блок. (Теперь, чтобы начать войну за скобки!) - person Axeman; 01.02.2010
comment
Также стоит упомянуть, что использование lib и непосредственное управление @INC не всегда эквивалентны операциям. Подробнее см. В документации. - person jrockway; 02.02.2010

В CPAN есть прагма only, которая упрощает установку и последующее использование нескольких версий одного и того же модуля.

person ysth    schedule 01.02.2010

Если вы предпочитаете, чтобы ваша логика выполнялась во время выполнения (например, если переменная $ new создается более сложным способом, который вы не хотите запускать в блоке BEGIN), вы можете использовать require () для загрузки модуля во время выполнения.

Важно помнить, что

use Module;
use ModuleWithExports qw(export1 export2);

Такой же как

BEGIN { require Module; Module->import() }
BEGIN {
    require ModuleWithExports;
    ModuleWithExports->import('export1', 'export2');
}

Это означает, что для запуска вашего кода во время выполнения вы можете просто иметь:

if ($new) {
    unshift @INC, "newdir";
}
else {
    unshift @INC, "olddir";
}
require module;
module->import(); # if necessary

Альтернативой использованию require () является использование Module :: Загрузить модуль из CPAN.

person Kaoru    schedule 02.02.2010