How can I use local hg repo libraries for testing isolating from already installed libs?
Installed production perl package and local hg repo has the same structure
+-- lib
|-- modA.pm
|-- modB.pm
+-- bin
|-- example.pl
+-- t
|-- modA.t
|-- modB.t
libraries installed at and the path is added to @PERL5
/nfs_share/perl/
env|grep -i perl
PERL5:/usr/local/perl:/nfs_share/perl
local hg repo at:
/data/user/hg/perl
modB.pm
#!/usr/bin/perl
use modA;
sub modB_compare{
my (x,y) = @_;
# .....
return x-y;
}
bin/example.pl
use FindBin qw($Bin);
use lib "${Bin}/lib/";
use modA, modB;
# if this call is from local lib
my $result = modB_compare(x,y);
# if sub being called from production or local hg?
my $result2 = modA_method();
# from local hg repo or from production lib?!
If I were to modify and test in local hg repo, there is no gurantee that the lib I called is from local repo, not from the production libs.
What is the potential solutions for isolation the libraries for testing in a local hg repo?
Short answer: for tests, just use prove -l
.
If I were to modify and test in local hg repo, there is no gurantee that the lib I called is from local repo, not from the production libs.
Actually, there is, for the problem you've defined.
If you know that ./lib/modA.pm
exists and ./lib/
in @INC
, then ./lib/modA.pm
will be loaded and any system perl version won't be*.
Your use lib
statement does this for you as documented in perlvar @INC and require.
However, for tests, it's normal practice not to use lib
, but instead use the -I
flag in perl (perl -Ilib t/modA.t
) or, better, prove, which also has a -l
flag, so you can just do prove -l
and it runs all the tests in t/
using the modules in ./lib
.
NB: You might also want to look into ExtUtils::MakeMaker or Module::Build::Tiny which help with distribution tasks, and you might want to consider Dist::Zilla or (for a quicker start) Dist::Milla
If you just want to verify what's going on You can check which files have been loaded in use
or require
statements by looking at %INC.
If you absolutely have to control what modules are accessible, for instance because you want to test different behaviour depending on whether third-party modules are installed (rather than your own code), I suggest looking into perlbrew. This will help you compile your own perl (of almost any vaguely recent version) which does not use the libraries from system perl, but instead has its own libraries, using local::lib
; you can then switch between multiple installed perls. The only exceptions are libraries that are packaged with perl itself; you can get a list of these from Module::Corelist.
Finally, you might want to check out Carton. I don't think it's quite what you're asking for but it's such a similar problem domain that I think it's worth a mention.
* OK, strictly, lib
has to appear in @INC
before the system perl lib directories, because what happens is that perl goes through @INC in order and finds files corresponding to the package name you have asked it to load; all of the methods you've used and that I'm talking about in this answer will make sure that your lib
directory appears earlier in @INC
then your system perl libs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With