Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

"use lib" with low precedence?

by joe++ (Friar)
on Oct 07, 2002 at 12:07 UTC ( #203298=perlquestion: print w/ replies, xml ) Need Help??
joe++ has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I'm developing a script on a box where I can't install modules. No problem, I just create a local libdir and add

#!/usr/bin/perl -w use lib qw(libdir);
That's classic.

Now this inserts the path libdir in front of @INC, which means that my local library will be ALWAYS used, regardless of the availability of the same module in the regular @INC paths.

This is not wat I want; I want to provide the local library only in case a global installed library is missing.

Now I was thinking about a solution where I require this specific module in an eval block instead of use-ing it, catch errors and require my local version if needed.

eval { require Test::Simple; }; if ($@) { eval { use lib qw(libdir); }; } eval { require Test::Simple; }; die $@ if $@;
However, this is more complicated and I don't get the benefit of compile-time checking of the used module.

Is there a better solution?

--
Cheers, Joe

Comment on "use lib" with low precedence?
Select or Download Code
Re: "use lib" with low precedence?
by PodMaster (Abbot) on Oct 07, 2002 at 12:14 UTC
    Yes, modify @INC instead of using lib ;)
    ## instead of the standard ## BEGIN { unshift(@INC, LIST) } ## do BEGIN { push(@INC, LIST) }
    It's important to take a look into the modules you use every once in a while, especially the pragmas ~ you'll learn a thing or two.

    BTW ~ I'm not sure how this will effect version issues, like if you "use CGI 2.81;", and your lib has it, but the standard lib has 2.71.

    update: If you're in the above situation, you could work some magic like in robustly list any Perl code's module dependencies and get fancy with it.

    ____________________________________________________
    ** The Third rule of perl club is a statement of fact: pod is sexy.

      Sure, that's exactly it... stupid me ;-)

      Update: the stupidiest question is still the unasked question - learnt a much better trick cf Abigail's tip below!

      Thanks again!

      --
      Cheers, Joe

Re: "use lib" with low precedence?
by broquaint (Abbot) on Oct 07, 2002 at 12:16 UTC
    Since use lib is really just a glorified unshift @INC you could just do a simple push e.g
    BEGIN { push @INC, qw( your/libraries here ) } ...
    Now your local libraries will have a 'lower precedence' than the system libraries.
    HTH

    _________
    broquaint

Re: "use lib" with low precedence?
by Abigail-II (Bishop) on Oct 07, 2002 at 12:28 UTC
    You can make use of the fact that lib::import deletes duplicates from @INC, and do:
    use lib @INC => "libdir";

    That will effectively put libdir after all the other directories in @INC.

    Abigail

      I like this trick better than manipulating @INC directly, as others have suggested.

      Seems like doing this is clearer and more likely to be robust if new magic is added to @INC at some point.

Re: "use lib" with low precedence?
by belg4mit (Prior) on Oct 07, 2002 at 16:17 UTC
    Finally...
    use lib 'foo'; use Fred; use Barney;

    is different from

    use Fred; use lib 'foo'; use Barney;

    UPDATE: To clarify, in the former both Fred and Barney are included from foo. In the latter Fred comes from the default location and Barney from foo; assuming copies of Fred and Barney exist in both foo and default locations.

    --
    perl -wpe "s/\b;([mnst])/'$1/g"

Re: "use lib" with low precedence?
by shahzbot (Novice) on Oct 07, 2002 at 22:49 UTC
    One other option, for those not wanting to modify their scripts at all: The PERL5LIB environment variable. If you do this:
    perl -e "print join(qq|:|, @INC)"
    

    you'll get your current perl @INC array in a path format. If you set your PERL5LIB env var to the output of that one-liner and also tack your own custom libs on the end of it, this will have the effect of putting a copy of your @INC in front of your custom libs, even though your original @INC remains untouched (and unused) at runtime. When I do this, my PERL5LIB ends up looking like this (breaks added for readability):
    /usr/lib/perl5/5.6.1/i386-linux:/usr/lib/perl5/5.6.1:
    /usr/lib/perl5/site_perl/5.6.1/i386-linux:
    /usr/lib/perl5/site_perl/5.6.1:/usr/lib/perl5/site_perl:.:
    /home/jtillman/customlibdir/
    

    It ends up doubling your original @INC path in memory, but as a temporary measure, it's much easier to reverse, since you have no code to modify. Just a thought... jpt

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (12)
As of 2015-07-03 07:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (48 votes), past polls