Мы посмотрим, как сконструировано содержимое этого массива, и с его помощью можно повлиять на то, где интерпретатор Perl найдет файлы модуля.
По умолчанию @INC
Perl-интерпретатор компилируется с определенным @INCзначением по умолчанию . Чтобы узнать это значение, запустите env -i perl -Vкоманду ( env -iигнорирует PERL5LIBпеременную окружения - см. # 2) и в выходных данных вы увидите что-то вроде этого:
$ env -i perl -V
...
@INC:
/usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/site_perl/5.18.0
/usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/5.18.0
.
Примечание .в конце; это текущий каталог (который не обязательно совпадает с каталогом скрипта). Он отсутствует в Perl 5.26+ и при работе с Perl -T(проверка на заражение включена) .
Чтобы изменить путь по умолчанию при настройке двоичной компиляции Perl, установите параметр конфигурации otherlibdirs:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
Экологическая переменная PERL5LIB(или PERLLIB)
Perl предварительно ожидает @INCсписок каталогов (разделенных двоеточиями), содержащихся в PERL5LIB(если он не определен, PERLLIBиспользуется) переменной среды вашей оболочки. Чтобы увидеть содержимое @INCпосле PERL5LIBи PERLLIBпеременных окружения вступили в силу, бег perl -V.
$ perl -V
...
%ENV:
PERL5LIB="/home/myuser/test"
@INC:
/home/myuser/test
/usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/site_perl/5.18.0
/usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/5.18.0
.
-I опция командной строки
Perl предварительно ожидает @INCсписок каталогов (разделенных двоеточиями), переданных в качестве значения параметра -Iкомандной строки. Это можно сделать тремя способами, как обычно, с помощью параметров Perl:
Передайте это в командной строке:
perl -I /my/moduledir your_script.pl
Передайте его через первую строку (shebang) вашего скрипта Perl:
#!/usr/local/bin/perl -w -I /my/moduledir
Передайте его как часть PERL5OPT(или PERLOPT) переменной окружения (см. Главу 19.02 в Программирование на Perl )
Передайте это через libпрагму
Perl предварительно ожидает @INCсписок каталогов, переданных ему черезuse lib .
В программе:
use lib ("/dir1", "/dir2");
В командной строке:
perl -Mlib=/dir1,/dir2
Вы также можете удалить каталоги с @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 переполнении стека нет поста типа FAQ, поэтому этот вопрос задуман как один.
Когда использовать каждый подход?
Если модули в каталоге должны использоваться многими / всеми сценариями на вашем сайте, особенно выполняемыми несколькими пользователями, этот каталог должен быть включен в стандартный каталог, @INCскомпилированный в двоичный файл Perl.
Если модули в каталоге будут использоваться исключительно конкретным пользователем для всех сценариев, которые запускает пользователь (или если перекомпиляция Perl не является опцией для изменения значения @INCпо умолчанию в предыдущем случае использования), установите пользователей PERL5LIB, обычно при входе пользователя в систему.
Примечание: Пожалуйста, имейте в виду обычные подводные камни переменных среды Unix - например, в некоторых случаях запуск сценариев от имени конкретного пользователя не гарантирует запуск их с настройкой среды этого пользователя, например, через su.
Если модули в каталоге необходимо использовать только при определенных обстоятельствах (например, когда сценарии выполняются в режиме разработки / отладки, вы можете установить их PERL5LIBвручную или передать -Iпараметр perl.
Если модули нужно использовать только для определенных сценариев, все пользователи, использующие их, используют use lib/ no libpragmas в самой программе. Его также следует использовать, когда каталог, который необходимо найти, должен быть динамически определен во время выполнения - например, из параметров командной строки сценария или пути сценария (см. Очень хороший пример использования в модуле 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? ).