【问题标题】:What's the search order in perl's include path when a module is loaded加载模块时perl的包含路径中的搜索顺序是什么
【发布时间】:2012-01-11 13:12:21
【问题描述】:

假设@INC 中有三个路径:path1path2path3。在这些路径中的每一个下,都有一个名为foo.pm 的模块。如果我现在通过use foo; 在我的脚本中加载foo.pm,那么实际上将加载哪个foo.pms?或者换句话说,perl 对@INC 中路径的搜索顺序是什么?

【问题讨论】:

标签: perl


【解决方案1】:

路径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,但很可能是您的某些路径搞砸了。

【讨论】:

  • \@Axeman:我打印@INC 并且打印的顺序是path1、path2 和path3,我也期望它的path1/foo.pm 已加载,但在我的情况下path3/foo.pm 是加载。这里有两种可能,一种是打印的顺序与搜索顺序相反,或者是什么疯狂的东西……
  • @HaiyuanZhang @INC 应该按顺序打印出来,因为它是一个列表。也许你在BEGIN 块之后运行的东西中对@INC 进行了一些操作(请记住use 是一个隐含的BEGIN 块)。因此,您可以编写如下代码:unshift @INC, qw</path1 /path2>;use foo; 并最终在路径 3 中实现 foo。文件中的顺序位置不一定规定顺序处理。见use
【解决方案2】:

perldoc -v %INC 显示选择了哪个路径:

use Data::Dumper; 
print Dumper(\%INC);

或者……

perl -Mfoo -e 'print $INC{"foo.pm"}'

require 显示了一些暗示搜索顺序的伪代码:

foreach $prefix (@INC) {
}

因此,path1 将首先被搜索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    相关资源
    最近更新 更多