Какие есть способы повлиять на поиск модулей Perl? или, как устроен Perl @INC ?
Как мы знаем, Perl использует @INC
массив, содержащий имена каталогов, чтобы определить, где искать файлы модулей Perl .
Похоже, что в StackOverflow нет подробного поста типа «@INC», поэтому этот вопрос задуман как один.
perl
perl-module
DVK
источник
источник
@INC
во время выполнения, а не о полной конструкции.Ответы:
Мы посмотрим, как сконструировано содержимое этого массива, и с его помощью можно повлиять на то, где интерпретатор Perl найдет файлы модуля.
По умолчанию
@INC
Perl-интерпретатор компилируется с определенным
@INC
значением по умолчанию . Чтобы узнать это значение, запуститеenv -i perl -V
команду (env -i
игнорируетPERL5LIB
переменную окружения - см. # 2) и в выходных данных вы увидите что-то вроде этого:Примечание
.
в конце; это текущий каталог (который не обязательно совпадает с каталогом скрипта). Он отсутствует в Perl 5.26+ и при работе с Perl-T
(проверка на заражение включена) .Чтобы изменить путь по умолчанию при настройке двоичной компиляции Perl, установите параметр конфигурации
otherlibdirs
:Экологическая переменная
PERL5LIB
(илиPERLLIB
)Perl предварительно ожидает
@INC
список каталогов (разделенных двоеточиями), содержащихся вPERL5LIB
(если он не определен,PERLLIB
используется) переменной среды вашей оболочки. Чтобы увидеть содержимое@INC
послеPERL5LIB
иPERLLIB
переменных окружения вступили в силу, бегperl -V
.-I
опция командной строкиPerl предварительно ожидает
@INC
список каталогов (разделенных двоеточиями), переданных в качестве значения параметра-I
командной строки. Это можно сделать тремя способами, как обычно, с помощью параметров Perl:Передайте это в командной строке:
Передайте его через первую строку (shebang) вашего скрипта Perl:
Передайте его как часть
PERL5OPT
(илиPERLOPT
) переменной окружения (см. Главу 19.02 в Программирование на Perl )Передайте это через
lib
прагмуPerl предварительно ожидает
@INC
список каталогов, переданных ему черезuse lib
.В программе:
В командной строке:
Вы также можете удалить каталоги с
@INC
помощьюno lib
.Вы можете напрямую манипулировать
@INC
как обычный массив Perl.Примечание: поскольку
@INC
используется на этапе компиляции, это должно быть сделано внутриBEGIN {}
блока, который предшествуетuse MyModule
оператору.Добавить каталоги в начало через
unshift @INC, $dir
.Добавить каталоги до конца через
push @INC, $dir
.Сделайте что-нибудь еще, что вы можете сделать с массивом Perl.
Примечание: каталоги сдвинут на
@INC
в порядке , указанном в этом ответе, например , по умолчанию@INC
является последним в списке, которым предшествуютPERL5LIB
, которому предшествует-I
, предшествуетuse lib
и прямой@INC
манипуляции, последние два смешиваться в зависимости от того , заказать их в коде Perl.Ссылки:
@INC
?Там не кажется всеобъемлющим
@INC
переполнении стека нет поста типа FAQ, поэтому этот вопрос задуман как один.Когда использовать каждый подход?
Если модули в каталоге должны использоваться многими / всеми сценариями на вашем сайте, особенно выполняемыми несколькими пользователями, этот каталог должен быть включен в стандартный каталог,
@INC
скомпилированный в двоичный файл Perl.Если модули в каталоге будут использоваться исключительно конкретным пользователем для всех сценариев, которые запускает пользователь (или если перекомпиляция Perl не является опцией для изменения значения
@INC
по умолчанию в предыдущем случае использования), установите пользователейPERL5LIB
, обычно при входе пользователя в систему.Примечание: Пожалуйста, имейте в виду обычные подводные камни переменных среды Unix - например, в некоторых случаях запуск сценариев от имени конкретного пользователя не гарантирует запуск их с настройкой среды этого пользователя, например, через
su
.Если модули в каталоге необходимо использовать только при определенных обстоятельствах (например, когда сценарии выполняются в режиме разработки / отладки, вы можете установить их
PERL5LIB
вручную или передать-I
параметр perl.Если модули нужно использовать только для определенных сценариев, все пользователи, использующие их, используют
use lib
/no lib
pragmas в самой программе. Его также следует использовать, когда каталог, который необходимо найти, должен быть динамически определен во время выполнения - например, из параметров командной строки сценария или пути сценария (см. Очень хороший пример использования в модуле FindBin ).Если каталогами
@INC
нужно манипулировать в соответствии с какой-то сложной логикой, которую невозможно или слишком громоздко реализовать с помощью комбинацииuse lib
/no lib
прагм, то используйте прямое@INC
манипулирование внутриBEGIN {}
блока или внутри специальной библиотеки, предназначенной для@INC
манипуляции, которая должна использоваться вашим сценарием (s) перед использованием любых других модулей.Примером этого является автоматическое переключение между библиотеками в каталогах prod / uat / dev, с водопадной библиотекой в prod, если она отсутствует в dev и / или UAT (последнее условие усложняет стандартное решение "use lib + FindBin". A подробные иллюстрации этого сценария в Как использовать бета - модули Perl из бета - скриптов на Perl? .
Дополнительный вариант использования для прямого манипулирования
@INC
- это возможность добавлять ссылки на подпрограммы или ссылки на объекты (да, Вирджиния@INC
может содержать собственный код Perl, а не только имена каталогов, как объясняется в разделе Когда вызывается ссылка на подпрограмму в @INC? ).источник
В дополнение к местам, перечисленным выше, версия Perl для OS X также имеет еще два способа:
Файл /Library/Perl/x.xx/AppendToPath. Пути, перечисленные в этом файле, добавляются к @INC во время выполнения.
Файл /Library/Perl/x.xx/PrependToPath. Пути, перечисленные в этом файле, добавляются к @INC во время выполнения.
источник
Как уже было сказано, @INC - это массив, и вы можете добавлять все, что захотите.
Мой скрипт CGI REST выглядит так:
Ушедшая подпрограмма экспортируется Rest.pm.
источник