Perl-интерпретатор (который запускает вашу программу perl) будет использовать специальный массив с именем @INC
для поиска файла, содержащего модуль.
Каждое значение в массиве @INC
- это имя каталога (, но см. Примечание ниже); Perl будет искать в этих каталогах в цикле, используя правила, указанные ниже. (См. this SO post for details of how the contents of @INC are determined).
Если файл модуля не найден после исчерпания @INC
, компиляция программы будет прервана с ошибкой. Если файл модуля находится в одном из каталогов, указанных в @INC
, поиск завершен, не глядя на остальную часть @INC
.
Путь Perl ищет файл модуля в каждом из каталогов, перечисленных в @INC
выглядит следующим образом:
Во-первых, это будет отдельный иерархические компоненты имя модуля в (слова, разделенные ::
), в последний компонент, который будет использоваться для формирования имени файла, и путь иерархии (все компоненты, предшествующие последним ::
).
В случае, если имя модуля имеет только один компонент (нет ::
, например MyModule1
), путь иерархии пуст, а имя файла - это имя модуля. Во втором примере в этом вопросе последний компонент равен MyModule2
, а путь иерархии будет This::Here
.
Ожидаемое имя файла будет определено путем добавления последнего компонента имени модуля с расширением .pm
. Например. MyModule1.pm
и MyModule2.pm
в наших примерах.
ПРИМЕЧАНИЕ. Имена модулей, очевидно, чувствительны к регистру в Unix и других операционных системах, где имена файлов/каталогов чувствительны к регистру.
каталог модуля будет определяться:
Принимая следующий каталог из @INC
- скажем /usr/lib/perl
качестве примера
Формирование подкаталог этого каталога, принимая иерархию путь имени модуля (если таковой имеется) и заменить «::» /
или любым другим символом, который операционная система использует как разделитель каталога. В наших двух примерах первый модуль будет искать в /usr/lib/perl
(без подкаталога), а второй - в /usr/lib/perl/This/Here
.
ПРИМЕЧАНИЕ: выше небольшое упрощение - @INC
may also contain subroutine references and object references, который загружает модули, как их пользовательский код указывает вместо выполнения поиск в каталоге, как указано в # 2 логика выше. Эта функциональность очень редко используется, и в этой статье предполагается, что весь @INC
содержит только каталоги.
Давайте рассмотрим конкретный пример, при условии, что ваш @INC
содержит две поддиректории: ("/usr/lib/perl", "/opt/custom/lib")
.
Тогда Perl будет искать следующим образом:
==========================================================================
| Module | Try # | File to try
==========================================================================
| MyModule1 | Try 1 | /usr/lib/perl/MyModule1.pm
| MyModule1 | Try 2 | /opt/custom/lib/MyModule1.pm
==========================================================================
| This::Here::MyModule2 | Try 1 | /usr/lib/perl/This/Here/MyModule2.pm
| This::Here::MyModule2 | Try 2 | /opt/custom/lib/This/Here/MyModule2.pm
==========================================================================
Пожалуйста, помните, что интерпретатор Perl перестанет пытаться искать, когда он находит файл в одном из мест, не пытаясь увидеть, если файл находится в более поздних местах также. Например. если /usr/lib/perl/This/Here/MyModule2.pm
существует, то Perl не будет искать и не заботится о существовании /opt/custom/lib/This/Here/MyModule2.pm
.
ПРИМЕЧАНИЕ: @INC используется всякий раз, когда интерпретатор Perl использует require
-подобный механизм для импорта модулей Perl. Это включает в себя:
require
директива сама
use MyModule
заявление (эквивалент требовать + импорт)
use base
(эквивалент требовать + "нажмите @ISA")
Я не смог найти исчерпывающий ответ на этот вопрос, на который я мог ссылаться, поэтому я решил создать его. Если приведенный ниже ответ нуждается в дополнениях/исправлениях, пожалуйста, имейте это в виду :) – DVK