简体   繁体   中英

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:

Is it a bad idea to use use lib or unshift @INC in the production code since they are hard to test? The prove -lvr cannot override these too.

Code 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

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

Output of 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 .
  • 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. Now /top/priority/use/lib/second_priority is at the beginning of @INC .
  • For the rest of the compilation phase, /top/priority/use/lib/second_priority is the first thing in @INC . That's where subsequent use calls will look for things.
  • The compilation phase finishes and the program transitions into the run phase.
  • It encounters the push and executes that. Now /push/inc/lowest_priority is the last element of @INC .
  • It skips over the use lib because the compilation phase handled the pragma.
  • It encounters the unshift and executes that. Now /unshift/inc/lib/first_priority is the first item in @INC .
  • Subsequent require calls (a runtime feature) will look in /unshift/inc/lib/first_priority first.

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.

I might be misunderstanding your problem but local::lib allows you to "manually" tune your module path. You should be able to use it to control what paths are used for your test environment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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