Как построен Perl's @INC? (ака, каковы все способы влияния на то, где ищут модули Perl?)

каковы все способы влияния на поиск модулей Perl? или, Как построен Perl's @INC?

Как известно, Perl использует @INC массив, содержащий имена каталогов, чтобы определить, где искать файлы модуль Perl.

Кажется, что нет всеобъемлющего сообщения типа FAQ" @INC " на StackOverflow, поэтому этот вопрос предназначен как один.

3 ответов


мы рассмотрим, как содержимое этого массива строится и может манипулировать, чтобы повлиять на то, где интерпретатор Perl найдет файлы модуля.

  1. по умолчанию @INC

    Perl интерпретатор скомпилировано с определенным @INC значение по умолчанию. Чтобы узнать это значение, запустите (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

  1. переменные среды PERL5LIB (или PERLLIB)

    Perl pre-pends @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
     .
    
  2. Perl pre-pends @INC со списком каталогов (разделенных двоеточием) передается как значение . Это можно сделать тремя способами, как обычно с вариантами Перл:

    • передайте его в командной строке:

      perl -I /my/moduledir your_script.pl
      
    • передайте его через первую строку (shebang) вашего Perl сценарий:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • передать его как часть PERL5OPT (или PERLOPT) переменной окружения (см. главу 19.02 в Программирование На Perl)

  3. передайте его через lib ПРАГМА

    Perl pre-pends @INC со списком каталогов, переданных ему через use lib.

    в программе:

    use lib ("/dir1", "/dir2");
    

    в командной строка:

    perl -Mlib=/dir1,/dir2
    

    вы можете удалить каталоги от @INC via no lib.

  4. вы можете напрямую манипулировать @INC как обычный массив Perl.

    Обратите Внимание:@INC используется на этапе компиляции, это должно быть сделано внутри BEGIN {} блок, который предшествует use MyModule заявление.

    • добавить каталоги в начало через unshift @INC, $dir.

    • добавить каталоги до конца через push @INC, $dir.

    • сделайте все, что вы можете сделать с массивом Perl.

Примечание: директории unshifted на @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 прагмы, затем используйте direct @INC манипуляции внутри BEGIN {} блок или внутри библиотеки специального назначения, предназначенной для @INC манипуляция, которая должна использоваться вашим скриптом(сценариями) перед использованием любых других модулей.

    примером этого является автоматическое переключение между библиотеками в каталогах prod/uat/dev, с подборкой библиотеки waterfall в prod, если она отсутствует в dev и / или UAT (последнее условие делает стандартное решение "использовать lib + FindBin" довольно сложное. Подробная иллюстрация этого сценария находится в как использовать модули beta Perl из сценариев beta Perl?.

  • дополнительный вариант использования для непосредственного управления @INC должен иметь возможность добавлять ссылки на подпрограммы или ссылки на объекты (да, Вирджиния,@INC может содержать пользовательский код Perl, а не только имена каталогов, как описано в когда ссылка на подпрограмму в @INC называется?).


в дополнение к местоположениям, перечисленным выше, версия OS X Perl также имеет еще два способа:

  1. The / Library / Perl / x.xx / файл AppendToPath. Пути, перечисленные в этом файле, добавляются в @INC во время выполнения.

  2. The / Library / Perl / x.файл xx / PrependToPath. Пути, перечисленные в этом файле, добавляются в @INC во время выполнения.


как уже было сказано, @INC-это массив, и вы можете добавить все, что захотите.

мой скрипт CGI REST выглядит так:

#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
    push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);

подпрограмма gone экспортируется Rest.pm.