Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Welcome to the Monastery
 
PerlMonks  

how to force Build test to load all modules from blib/lib first

by rbroberts (Initiate)
on Nov 22, 2012 at 02:46 UTC ( #1005042=perlquestion: print w/ replies, xml ) Need Help??
rbroberts has asked for the wisdom of the Perl Monks concerning the following question:

I have "family" of modules that I'm having trouble testing. Roughly, the hierarchy looks like
use A::B::C1; use A::B::C2; use A::B::C1::D;
"A" is an acronym for our development group, so all of our perl modules start with that. In A::B::C2 and A::B::C1::D there is a line like
use A::X;
What seems to be happening is that A::B and A::B::C2 are loaded from blib/lib, then A::B::C1::D gets loaded from the installed area which is in PERL5LIB. That is also where A::X lives. If I flip the order to the use lines to
use A::B::C1; use A::B::C1::D; use A::B::C2;
Then A::B::C1::D is loaded from blib/lib and A::B::C2 is loaded from the installed area. I can't find any way to make sure that all three of the packages in this family get loaded from blib/lib. I've tried playing with @INC with no luck. How can I convince Perl to use blib/lib first for all of my modules?

Comment on how to force Build test to load all modules from blib/lib first
Select or Download Code
Re: how to force Build test to load all modules from blib/lib first
by muba (Priest) on Nov 22, 2012 at 03:13 UTC

    Perhaps something like BEGIN { unshift @INC, "./blib/lib"; } will work?

      I already have a BEGIN block in the test, like this
      #! /usr/bin/env perl use Test::More tests => 7; use POSIX qw(strftime); use lib "$ENV{FVIS_HOME}/monitor/lib"; use lib "$ENV{FVIS_HOME}/monitor/tools"; BEGIN { use Cwd; use File::Path; use File::Basename qw(basename dirname); my $tmpdir = &getcwd() . "/test/" . basename($0); rmtree($tmpdir); mkpath("$tmpdir/log"); mkpath("$tmpdir/monitor/schedule"); mkpath("$tmpdir/monitor/etc"); symlink("$ENV{FVIS_HOME}/lib", "$tmpdir/lib"); symlink("$ENV{FVIS_HOME}/etc", "$tmpdir/etc"); $ENV{FVIS_HOME} = $tmpdir; $ENV{GUMS_ROOT} = "$tmpdir/monitor"; unshift(@INC, "$ENV{FVIS_HOME}/lib/perl"); unshift(@INC, "./blib/lib"); } use FVIS::Rachlis::Job; use FVIS::Rachlis::Schedule::File; use FVIS::Rachlis::Schedule;
      What this is doing is setting up a sandbox linking parts to the actual installed area. The behavior with our without the two unshift() is the same. Both FVIS::Rachlis::Job and FVIS::Rachlis::Schedule::File; are loaded from blib/lib, FVIS::Rachlis::Schedule is loaded from $ENV{FVIS_HOME}/lib/perl which is already in PERL5LIB. Both load FVIS::Log which wraps part of Log::Log4perl. Flipping the order of the last two flips which one is loaded from blib/lib.
Re: how to force Build test to load all modules from blib/lib first
by Anonymous Monk on Nov 22, 2012 at 04:09 UTC

    How can I convince Perl to use blib/lib first for all of my modules?

    You don't need to convince it, this is what it does already. For this behavior to change, your code must be to blame.

      blib/lib is in @INC, but it is there in the "wrong" place; well, it's not at the front. It's a bit hard to figure out exactly what is happening because when running with -d, the modules are already loaded since that happens at compile time.
Re: how to force Build test to load all modules from blib/lib first
by 2teez (Priest) on Nov 22, 2012 at 04:15 UTC

    Hi rbroberts,

    "..I've tried playing with @INC with no luck.." How?

    Have you tired lib, like so:

    use lib "./blib/lib";

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      blib is for blib, and Module::Build/ExtUtils::MakeMaker/Module::Install... all do it by default, and even prove has a -b switch to load blib

        All of those put blib/lib near the front of @INC. In spite of that, something weird is going on with module load order. Since it's happening at compile time, I can only see the state after the loads at which point %INC shows the wrong module loaded for the one.
Re: how to force Build test to load all modules from blib/lib first
by Anonymous Monk on Nov 22, 2012 at 04:46 UTC
    What is your perl -V
      I assume its PERL5LIB and @INC you mostly want to see, but here is the whole thing:
      260 roland> perl -V Summary of my perl5 (revision 5 version 14 subversion 3) configuration +: Platform: osname=linux, osvers=2.6.32-279.9.1.el6.x86_64, archname=x86_64-li +nux-thread-multi uname='linux buildvm-03.phx2.fedoraproject.org 2.6.32-279.9.1.el6. +x86_64 #1 smp fri aug 31 09:04:24 edt 2012 x86_64 x86_64 x86_64 gnuli +nux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOU +RCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 +-mtune=generic -Dccdlflags=-Wl,--enable-new-dtags -Dlddlflags=-shared + -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-prot +ector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wl,-z,relro -D +DEBUGGING=-g -Dversion=5.14.3 -Dmyhostname=localhost -Dperladmin=root +@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefi +x=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsit +earch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/ +usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/ +usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dli +bpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Du +seithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_sem +un -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duse +perlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/u +sr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_se +thostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_ +endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und +ef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasin +g -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D +_FILE_OFFSET_BITS=64', optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions +-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -f +stack-protector -I/usr/local/include' ccversion='', gccversion='4.7.2 20120921 (Red Hat 4.7.2-2)', gccos +andvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1 +6 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', + lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags =' -fstack-protector' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread +-lc -lgdbm_compat perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.15' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--en +able-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_F +ORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-siz +e=4 -m64 -mtune=generic -Wl,-z,relro ' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP PERL_PRESERVE_IVUV USE_64_BIT_ALL USE_64_BIT_I +NT USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_PE +RL_ATOF USE_REENTRANT_API Built under linux Compiled at Oct 18 2012 13:31:24 %ENV: PERL5LIB="/fvisb/lib/perl:/fvisb/local/lib/perl5:/fvisb/local/lib/ +perl5/site_perl:/fvisb/local/lib/perl5/site_perl/5.14.3:/fvisb/local/ +lib/perl5/site_perl/5.14.3/x86_64-linux-thread-multi:/fvisb/local/lib +64/perl5:/fvisb/local/lib64/perl5/site_perl:/fvisb/local/lib64/perl5/ +site_perl/5.14.3:/fvisb/local/lib64/perl5/site_perl/5.14.3/x86_64-lin +ux-thread-multi:/fvisb/local/lib64/perl5/5.14.3/x86_64-linux-thread-m +ulti:/fvisb/local/lib64/perl5/5.14.3" @INC: /fvisb/lib/perl /fvisb/local/lib/perl5 /fvisb/local/lib/perl5/site_perl /fvisb/local/lib/perl5/site_perl/5.14.3 /fvisb/local/lib/perl5/site_perl/5.14.3/x86_64-linux-thread-multi /fvisb/local/lib64/perl5 /fvisb/local/lib64/perl5/site_perl /fvisb/local/lib64/perl5/site_perl/5.14.3 /fvisb/local/lib64/perl5/site_perl/5.14.3/x86_64-linux-thread-mult +i /fvisb/local/lib64/perl5/5.14.3/x86_64-linux-thread-multi /fvisb/local/lib64/perl5/5.14.3 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .
Re: how to force Build test to load all modules from blib/lib first
by rbroberts (Initiate) on Nov 22, 2012 at 11:53 UTC
    Found it! The common module was loading yet another common module that included "use lib ..." that was putting the installed area back in front of blib/lib. I'm beginning to think use lib is evil and PERL5LIB is a much better approach througout.

      I'm beginning to think use lib is evil and PERL5LIB is a much better approach througout.

      No, lib is not evil, lib simply doesn't belong in modules, it belongs in scripts

        Here is patch for lib.pm, add to sub import

        if( ( caller )[1] =~ /\.pm$/ ){ require Carp; Carp::croak( "use lib ... is for scripts not modules!"); }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1005042]
Approved by muba
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (16)
As of 2014-04-17 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (449 votes), past polls