简体   繁体   English

PERL5LIB,@ INC和库优先级进行测试

[英]PERL5LIB, @INC and library priority for testing

I had some difficulties in overriding perl lib when testing perl codes when the .pl or .pm has use lib or unshift @INC , my question is: .pl.pm use libunshift @INC时测试perl代码时,在覆盖perl lib时遇到一些困难,我的问题是:

Is it a bad idea to use use lib or unshift @INC in the production code since they are hard to test? 在生产代码中use libunshift @INC是一个坏主意,因为它们很难测试? The prove -lvr cannot override these too. prove -lvr也不能覆盖这些。

Code test.pl 代码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=>$inc\n";
}

set perl env 设置perl环境

export PERL5LIB=/export/PERL5LIB/env/lib:$PERL5LIB

Output of perl -I/cmd/Iinclude/lib/ test.pl 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

I don't hard-code paths unless I have no other options. 除非没有其他选择,否则我不会硬编码路径。

In general, you don't want to hardcode things that you can provide to your program in some other fashion so it can respond to whatever environment it's in rather than only the environment where you developed it. 通常,您不希望以其他方式对可以提供给程序的内容进行硬编码,以便它可以响应所处的任何环境,而不仅仅是对开发环境的响应。 One of those environments could be your testing environment. 这些环境之一可能是您的测试环境。

You can set the library search path from outside the program, and that makes it more flexible. 您可以从程序外部设置库搜索路径,这使其更加灵活。

And, since you hard-code them and add them at runtime, they are going to come after anything you've set previously. 而且,由于您对它们进行了硬编码并在运行时添加它们,因此它们将遵循您之前设置的所有内容。 Here's what happens in your setting: 在您的设置中会发生以下情况:

  • You start with the default @INC . 您从默认的@INC开始。
  • You start to "run" your program, you start the compilation phase. 您开始“运行”程序,然后开始编译阶段。 It compiles the entire program before it executes run-time statements. 它在执行运行时语句之前先编译整个程序。
  • As it compiles, it encounters the use lib and executes that pragma immediately. 在编译时,它将遇到use lib并立即执行该编译指示。 Now /top/priority/use/lib/second_priority is at the beginning of @INC . 现在/top/priority/use/lib/second_priority@INC的开头。
  • For the rest of the compilation phase, /top/priority/use/lib/second_priority is the first thing in @INC . 在其余的编译阶段, /top/priority/use/lib/second_priority@INC的第一件事。 That's where subsequent use calls will look for things. 在那儿,后续use调用将寻找东西。
  • The compilation phase finishes and the program transitions into the run phase. 编译阶段完成,程序过渡到运行阶段。
  • It encounters the push and executes that. 它遇到push并执行。 Now /push/inc/lowest_priority is the last element of @INC . 现在/push/inc/lowest_priority@INC的最后一个元素。
  • It skips over the use lib because the compilation phase handled the pragma. 因为编译阶段处理了编译指示,所以它跳过了use lib
  • It encounters the unshift and executes that. 它遇到不unshift并执行该动作。 Now /unshift/inc/lib/first_priority is the first item in @INC . 现在/unshift/inc/lib/first_priority@INC的第一项。
  • Subsequent require calls (a runtime feature) will look in /unshift/inc/lib/first_priority first. 随后的require调用(运行时功能)将首先在/unshift/inc/lib/first_priority

I don't know where you expect to find the library you expected to load, but you have to supply the full path to it. 我不知道您期望在哪里找到期望加载的库,但是您必须提供它的完整路径。 There may be extra directories under the lib/ that matter and you haven't accounted for. lib /下可能有其他重要的目录,您尚未考虑。

I might be misunderstanding your problem but local::lib allows you to "manually" tune your module path. 我可能会误解您的问题,但是local::lib允许您“手动”调整模块路径。 You should be able to use it to control what paths are used for your test environment. 您应该能够使用它来控制用于测试环境的路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM