如果我的 Perl 程序使用 Perl 模块,它将如何确定在哪里找到包含模块代码的文件?
例如,如果程序包含:
use MyModule1; # Example 1
use This::Here::MyModule2; # Example 2
它会看起来在哪里?
Perl 解释器(运行你的 Perl 程序)将使用一个特殊的数组,称为@INC
搜索包含该模块的文件。
中的每个值@INC
数组是目录名称(但请参阅下面的注释); Perl 将使用下面指定的规则在循环中搜索这些目录。 (请参阅这篇 SO 帖子详细介绍了如何确定 @INC 的内容 https://stackoverflow.com/questions/2526804/how-is-perls-inc-constructed-aka-what-are-all-the-ways-of-affecting-where-per).
如果穷尽之后没有找到模块的文件@INC
,程序的编译将因错误而中止。如果在指定的目录之一中找到模块的文件@INC
,搜索完成,无需查看其余部分@INC
.
Perl 在列出的每个目录中搜索模块文件的方式@INC
如下:
-
首先,它将分隔模块名称的分层组件(用 分隔的单词)::
),进入最后一个组件(将用于形成文件名)和层次结构路径(最后一个组件之前的所有组件)::
).
如果模块名称只有一个组成部分(没有::
, e.g. MyModule1
上面),层次结构路径为空,文件名是模块的名称。在这个问题的第二个例子中,最后一个组件是MyModule2
层次结构路径将是This::Here
.
-
预期的文件名将通过在模块名称的最后一个部分附加一个.pm
扩大。例如。MyModule1.pm
and MyModule2.pm
在我们的例子中。
注意:在 Unix 和其他文件/目录命名区分大小写的操作系统上,模块名称显然区分大小写。
-
模块的目录将由以下因素确定:
从中获取下一个目录@INC
- 比方说/usr/lib/perl
举个例子
通过获取模块名称(如果有)的层次结构路径并将“::”替换为该目录的子目录/
或操作系统用作目录分隔符的任何字符。在我们的两个示例中,将在以下位置搜索第一个模块/usr/lib/perl
(无子目录)和第二个/usr/lib/perl/This/Here
.
NOTE:上面是稍微简化的 -@INC
还可能包含子例程引用和对象引用 https://stackoverflow.com/questions/2541119/when-is-a-subroutine-reference-in-inc-called,它按照自定义代码指定的方式加载模块,而不是按照上面#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
.
注意:每当 Perl 解释器使用时,都会使用 @INCrequire
类似导入 Perl 模块的机制。这包括:
-
require
指令本身
-
use MyModule
语句(相当于require+import)
-
use base http://search.cpan.org/~rgarcia/base-2.14/lib/base.pm(相当于require+"push @ISA")
-
-M
命令行参数
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)