DVK*_*DVK 198 perl perl-module
影响Perl模块搜索位置的所有方法是什么?或者,Perl的@INC是如何构建的?
我们知道,Perl使用@INC包含目录名的数组来确定搜索Perl模块文件的位置.
在StackOverflow上似乎没有全面的"@INC"FAQ类型的帖子,所以这个问题是一个问题.
DVK*_*DVK 254
我们将看看如何构造这个数组的内容,并且可以对它进行操作以影响Perl解释器找到模块文件的位置.
默认 @INC
Perl解释器使用特定的@INC默认值进行编译.要查找此值,请运行env -i perl -V命令(env -i忽略PERL5LIB环境变量 - 请参阅#2),在输出中您将看到如下内容:
Run Code Online (Sandbox Code Playgroud)$ 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使用)shell的环境变量.要查看@INCafter PERL5LIB和PERLLIB环境变量的内容已生效,请运行perl -V.
Run Code Online (Sandbox Code Playgroud)$ 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
Run Code Online (Sandbox Code Playgroud)通过Perl脚本的第一行(shebang)传递它:
#!/usr/local/bin/perl -w -I /my/moduledir
Run Code Online (Sandbox Code Playgroud)将其作为PERL5OPT(或PERLOPT)环境变量的一部分传递(参见Perl编程中的第19.02章)
Perl预先挂起@INC了一个通过它传递给它的目录列表use lib.
在一个程序中:
use lib ("/dir1", "/dir2");
Run Code Online (Sandbox Code Playgroud)
在命令行上:
perl -Mlib=/dir1,/dir2
Run Code Online (Sandbox Code Playgroud)
您也可以从@INCvia中删除目录no lib.
您可以直接操作@INC为常规Perl数组.
注意:由于@INC在编译阶段使用,因此必须BEGIN {}在use MyModule语句之前的块内完成.
通过添加目录到开头unshift @INC, $dir.
通过添加目录到最后push @INC, $dir.
使用Perl数组做任何其他事情.
注:该目录未移动到@INC在这个回答中列出的顺序,比如默认@INC是在列表的最后,通过前面PERL5LIB,前面加-I,前面有use lib直接@INC操纵,后两者在他们在Perl代码为准顺序混合.
@INC?@INC在Stack Overflow上似乎没有一个全面的FAQ类型的帖子,所以这个问题是一个问题.
如果目录中的模块需要由您站点上的许多/所有脚本使用,尤其是由多个用户运行,那么该目录应该包含在@INC编译到Perl二进制文件中的默认目录中.
如果目录中的模块将由特定用户专门用于用户运行的所有脚本(或者如果重新编译Perl不是@INC在以前的用例中更改默认值的选项),则PERL5LIB通常在用户登录期间设置用户' .
注意:请注意通常的Unix环境变量缺陷 - 例如在某些情况下运行脚本,因为特定用户不保证在设置该用户的环境时运行它们,例如通过su.
如果目录中的模块只需要在特定情况下使用(例如,在开发/调试模式下执行脚本时,您可以PERL5LIB手动设置,也可以将-I选项传递给perl.
如果模块只需要用于特定脚本,所有使用它们的用户都需要在程序本身中使用use lib/ no libpragma.当需要在运行时期间动态确定要搜索的目录时,也应该使用它 - 例如,从脚本的命令行参数或脚本的路径(请参阅FindBin模块以获得非常好的用例).
如果@INC需要根据某些复杂的逻辑操作目录,或者通过组合use lib/ no libpragma 实现不太笨重,那么@INC在BEGIN {}块内或指定用于@INC操作的专用库内部使用直接操作,这必须由脚本使用(s)在使用任何其他模块之前.
这方面的一个例子是在prod/uat/dev目录中的库之间自动切换,如果dev和/或UAT中缺少了瀑布库,那么它就会被丢弃(最后一个条件使标准的"使用lib + FindBin"解决方案相当复杂.此方案的详细说明是如何使用从公测Perl脚本测试Perl模块?.
直接操作的另一个用例@INC是能够添加子例程引用或对象引用(是的,弗吉尼亚州,@INC可以包含自定义Perl代码而不仅仅是目录名称,如在@INC中的子例程引用何时调用?中所述).
dga*_*ood 17
除了上面列出的位置,Perl的OS X版本还有两种方法:
/Library/Perl/x.xx/AppendToPath文件.此文件中列出的路径在运行时附加到@INC.
/Library/Perl/x.xx/PrependToPath文件.此文件中列出的路径在运行时预先附加到@INC.
小智 6
正如所说的那样@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(@_);
Run Code Online (Sandbox Code Playgroud)
子程序消失由Rest.pm导出.
| 归档时间: |
|
| 查看次数: |
141929 次 |
| 最近记录: |