【发布时间】:2012-01-11 13:12:21
【问题描述】:
假设@INC 中有三个路径:path1、path2 和path3。在这些路径中的每一个下,都有一个名为foo.pm 的模块。如果我现在通过use foo; 在我的脚本中加载foo.pm,那么实际上将加载哪个foo.pms?或者换句话说,perl 对@INC 中路径的搜索顺序是什么?
【问题讨论】:
标签: perl
假设@INC 中有三个路径:path1、path2 和path3。在这些路径中的每一个下,都有一个名为foo.pm 的模块。如果我现在通过use foo; 在我的脚本中加载foo.pm,那么实际上将加载哪个foo.pms?或者换句话说,perl 对@INC 中路径的搜索顺序是什么?
【问题讨论】:
标签: perl
路径1、路径2、路径3。 perl 会加载path1/foo.pm。
为什么你会期望它是其他的?
看看perlfunc perlvar,我可以看到他们没有明确这么说,但他们确实说:
数组 @INC 包含 do EXPR 、 require 或 use 构造查找其库文件的位置列表。
我认为那里的提示是 list。期望 list 从头到尾处理是正常的。
您可以将这段代码放在您的 use foo; 声明之前:
BEGIN { say "\@INC=(${\join( ', ', @INC )})"; }
如果这仍然显示@INC=(/path1, /path2, /path3),则将其放在use 语句之后:
BEGIN { say "\$INC{'foo.pm'}=$INC{'foo.pm'}"; }
如果那个仍然显示$INC{'foo.pm'}=/path3/foo.pm,那么我认为您没有像您可能的那样指定您的搜索路径。您可能认为在指定为“/path1”的同一目录中有foo.pm,但很可能是您的某些路径搞砸了。
【讨论】:
@INC 应该按顺序打印出来,因为它是一个列表。也许你在BEGIN 块之后运行的东西中对@INC 进行了一些操作(请记住use 是一个隐含的BEGIN 块)。因此,您可以编写如下代码:unshift @INC, qw</path1 /path2>;use foo; 并最终在路径 3 中实现 foo。文件中的顺序位置不一定规定顺序处理。见use
perldoc -v %INC 显示选择了哪个路径:
use Data::Dumper;
print Dumper(\%INC);
或者……
perl -Mfoo -e 'print $INC{"foo.pm"}'
require 显示了一些暗示搜索顺序的伪代码:
foreach $prefix (@INC) {
}
因此,path1 将首先被搜索。
【讨论】: