Мы посмотрим, как сконструировано содержимое этого массива, и с его помощью можно повлиять на то, где интерпретатор 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
Передайте его через первую строку (шебанг) вашего скрипта Perl:
#!/usr/local/bin/perl -w -I /my/moduledir
Передать его как часть переменной среды PERL5OPT
(или PERLOPT
) (см. Главу 19.02 в Программирование на Perl )
Передайте его через lib
pragma
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 lib
в самой программе. Он также должен использоваться, когда каталог, который нужно искать, должен быть динамически определен во время выполнения - например, из параметров командной строки скрипта или пути скрипта (см. очень хороший пример использования в модуле FindBin ).
Если каталогами в @INC
нужно манипулировать в соответствии с какой-то сложной логикой, которую невозможно или слишком громоздко реализовать с помощью комбинации прагм use lib
/ no lib
, то используйте прямую манипуляцию @INC
внутри BEGIN {}
блок или внутри специальной библиотеки, предназначенной для манипуляций @INC
, которые должны использоваться вашими скриптами перед использованием любых других модулей.
Примером этого является автоматическое переключение между библиотеками в каталогах prod / uat / dev, с выбором библиотеки водопадов в prod, если он отсутствует в dev и / или UAT (последнее условие делает стандартное решение «use lib + FindBin» справедливым сложно.
Подробная иллюстрация этого сценария приведена в Как использовать бета-модули Perl из бета-скриптов Perl? .
Дополнительный вариант использования для прямого манипулирования @INC
- возможность добавлять ссылки на подпрограммы или ссылки на объекты (да, Вирджиния, @INC
может содержать собственный код Perl, а не только имена каталогов, как объяснено в Когда вызывается ссылка на подпрограмму в @INC? ).