Perl: как разделить импорт большого списка модулей между многими независимыми скриптами?

У меня много автономных скриптов. Единственное, что они разделяют, это то, что они используют() большой набор модулей CPAN (каждый из них экспортирует несколько функций). Я хотел бы централизовать этот список модулей. Я нашел несколько методов. Какой из них лучше?

  • Я могу создать SharedModules.pm, который импортирует все, а затем вручную экспортирует все в main:: using Exporter.

  • Я могу создать SharedModules.pm, который начинается с "main package"; поэтому он будет импортироваться непосредственно в main::. Кажется, это работает. Это плохая практика и почему?

  • Мне может потребоваться() sharedmodules.pl, который, кажется, импортирует все в main::. Мне не нравится этот метод, поскольку require() не работает так хорошо в mod_perl.

Номер два выглядит лучше всего для меня, однако мне интересно, почему, например, Modern:: Perl не работает именно так.

Изменить: я понял, что этот вопрос был задан до.

Ответ 1

Проблема со всеми тремя предложенными вами решениями заключается в том, что модуль может быть use d из другого модуля, и в этом случае символы должны быть экспортированы в пакет модуля use, а не в main.

bvr решение использовать caller для импорта вещей непосредственно в этот пакет является важным шагом в правильном направлении, но не позволяет "реальному" пакету использовать use ShareableModules qw( foo bar baz);, чтобы выборочно импортировать только то, что ему действительно нужно.

К сожалению, для сохранения возможности выборочного импорта вам потребуется импортировать все соответствующие символы из базовых модулей, а затем повторно экспортировать их из ShareableModules. Вы не можете просто делегировать импорт для каждого метода нижележащего модуля import (как это делает Modern::Perl), потому что import умирает, если запрашивает символ, который не экспортируется этим модулем. Если это не проблема, то способ Modern::Perl, возможно, самый простой и простой вариант.

Ответ 2

Возможно, более гибко, чем помещать все в пространство имен main, было бы импортировать в пространство имен вызывающих. Что-то вроде этого:

package SharedModules;

sub import {

    my $pkg = (caller())[0];
    eval <<"EOD";

package $pkg;

use List::Util;
use List::MoreUtils;

EOD

    die [email protected] if [email protected];
}

1;

Ответ 3

Использование require - самый естественный способ сделать это. В mod_perl вам может потребоваться изменить @INC во время запуска сервера.

Ответ 4

Возможно, вы хотите Toolkit.

Ответ 5

Файл import.pl:

require blah;  blah->import;
require blubb; blubb->import;

Skripts:

#!/usr/bin/perl
do 'import.pl'
...

Патрик