当.pl
或.pm
use lib
或unshift @INC
时,我在测试perl代码时在覆盖perl lib时遇到了一些困难,我的问题是:
在生产代码中使用
use lib
或unshift @INC
是一个坏主意,因为它们很难测试?prove -lvr
也不能覆盖这些。
代码test.pl
push @INC, '/push/inc/lowest_priority';
use lib "/top/priority/use/lib/second_priority";
unshift @INC, "/unshift/inc/lib/first_priority";
foreach my $inc (@INC){
print "INC=>$incn";
}
设置perl env
export PERL5LIB=/export/PERL5LIB/env/lib:$PERL5LIB
perl -I/cmd/Iinclude/lib/ test.pl
输出
INC=>/unshift/inc/lib/first_priority
INC=>/top/priority/use/lib/second_priority
INC=>/cmd/Iinclude/lib/
INC=>/export/PERL5LIB/env/lib
INC=>/usr/local/lib64/perl5
INC=>/usr/local/share/perl5
INC=>/usr/lib64/perl5/vendor_perl
INC=>/usr/share/perl5/vendor_perl
INC=>/usr/lib64/perl5
INC=>/usr/share/perl5
INC=>/push/inc/lowest_priority
除非我没有其他选择,否则我不对路径进行硬编码。
通常,您不希望对能够以其他方式提供给程序的内容进行硬编码,以便它可以响应它所处的任何环境,而不仅仅是您开发它的环境。其中一个环境可能是您的测试环境。
您可以从程序外部设置库搜索路径,这使其更加灵活。
而且,由于您对它们进行硬编码并在运行时添加它们,因此它们将在您之前设置的任何内容之后出现。以下是您的设置中发生的情况:
- 从默认
@INC
开始。 - 你开始"运行"你的程序,你开始编译阶段。它在执行运行时语句之前编译整个程序。
- 编译时,它会遇到
use lib
并立即执行该编译指示。现在/top/priority/use/lib/second_priority
正处于@INC
的开始。 - 对于编译阶段的其余部分,
/top/priority/use/lib/second_priority
是@INC
的第一件事。这就是后续use
调用将查找内容的地方。 - 编译阶段结束,程序过渡到运行阶段。
- 它遇到
push
并执行该。现在/push/inc/lowest_priority
是@INC
的最后一个元素。 - 它跳过
use lib
,因为编译阶段处理杂注。 - 它遇到
unshift
并执行该。现在/unshift/inc/lib/first_priority
是@INC
的第一项。 - 后续
require
调用(运行时功能)将首先查找/unshift/inc/lib/first_priority
。
我不知道您希望在哪里找到要加载的库,但您必须提供它的完整路径。lib/下可能有额外的目录很重要,你还没有考虑到。
我可能误解了您的问题,但local::lib
允许您"手动"调整模块路径。您应该能够使用它来控制用于测试环境的路径。