Perl's @INC是如何构建的?(又名:影响Perl模块搜索位置的所有方法是什么?)

影响Perl模块搜索位置的所有方法是什么? 或者,Perl的@INC是如何构造的吗?< / p >

如我们所知,Perl使用包含目录名的@INC数组来确定在哪里搜索Perl模块文件

在StackOverflow上似乎没有一个全面的“@INC”常见问题类型的帖子,所以这个问题是一个。

156539 次浏览

我们将看看这个数组的内容是如何构造的,以及如何操作它来影响Perl解释器在哪里找到模块文件。

  1. < p > @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

  1. 环境变量PERL5LIB(或PERLLIB)

    Perl将shell的环境变量PERL5LIB(如果没有定义,则使用PERLLIB)中包含的目录列表(以冒号分隔)预先挂起@INC。在PERL5LIBPERLLIB环境变量生效后,执行perl -V命令查看@INC的内容。

    $ 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. -I命令行选项

    Perl在@INC前挂起一个目录列表(冒号分隔),作为-I命令行选项的值传递。这可以通过三种方式完成,通常使用Perl选项:

    • 在命令行上传递它:

      perl -I /my/moduledir your_script.pl
      
    • Pass it via the first line (shebang) of your Perl script:

      #!/usr/local/bin/perl -w -I /my/moduledir
      
    • Pass it as part of PERL5OPT (or PERLOPT) environment variable (see chapter 19.02 in Programming Perl)

  3. Pass it via the lib pragma

    Perl pre-pends @INC with a list of directories passed in to it via use lib.

    In a program:

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

    在命令行中:

    perl -Mlib=/dir1,/dir2
    

    你也可以通过__ABC1删除@INC中的目录.

  4. 你可以直接操作@INC作为一个常规的Perl数组。

    注意:由于在编译阶段使用了@INC,这必须在use MyModule语句之前的BEGIN {}块中完成。

    • 通过unshift @INC, $dir将目录添加到开头。

    • 通过push @INC, $dir将目录添加到末尾。

    • 使用Perl数组可以做任何其他事情。

    • 李< / ul > < / >

注意:目录从未移位@INC,按照答案中列出的顺序,例如默认的@INC在列表的最后,前面是PERL5LIB,前面是-I,前面是use lib和直接的@INC操作,后两者在Perl代码中按照它们的顺序混合。

引用:

在Stack Overflow上似乎没有一个全面的@INC faq类型的帖子,所以这个问题是一个。

何时使用每种方法?

除了上面列出的位置之外,OS X版本的Perl还有两种方法:

  1. /图书馆/ Perl / x。xx / AppendToPath文件。该文件中列出的路径在运行时被追加到@INC。

  2. /图书馆/ 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(@_);

Rest.pm导出子例程gone。