srinigs has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,
One of the modules used in my script is present in more than one location (say path1 and path2) and I always want the one at path2 to be picked up. Also all the other modules should be picked up only from path1 even if they are present in path2.

I have specified "use lib path2" but it still always picks up the one at path1. The code is something like 'eval "use P4";' somewhere in the middle of the script (not written by me) and to debug I have added the following just before the eval statement:

if (require "P4.pm") { print "$INC{"P4.pm"}; }
This print always gives path1.

I also tried unshift ("path2", @INC) before eval, to make sure it is available right at the beginning of the array but it still ends up picking path1. Just to check I removed path1 from @INC and surprisingly the print statement still gives "path1"!

How do I go about achieving what I have specified at the top?Kindly help.

Also, moving around the modules to the right location or leaving out one of the paths is not an option :(

Thanks much,
srinigs

Replies are listed 'Best First'.
Re: Picking up a module from a specific location
by kcott (Archbishop) on Sep 11, 2012 at 06:50 UTC

    Your unshift syntax is incorrect. With the correct syntax, this technique works for me.

    Without modifying @INC:

    $ perl -Mstrict -Mwarnings -E ' require Const::Fast; + say $Const::Fast::VERSION; say $INC{q{Const/Fast.pm}}; ' 0.011 /Users/ken/perl5/perlbrew/perls/perl-5.14.2_WITH_THREADS/lib/site_perl +/5.14.2/Const/Fast.pm

    Modifying @INC with the normal path:

    $ perl -Mstrict -Mwarnings -E ' unshift @INC => q{/Users/ken/perl5/perlbrew/perls/perl-5.14.2_WITH_THR +EADS/lib/site_perl/5.14.2}; require Const::Fast; shift @INC; say $Const::Fast::VERSION; say $INC{q{Const/Fast.pm}}; ' 0.011 /Users/ken/perl5/perlbrew/perls/perl-5.14.2_WITH_THREADS/lib/site_perl +/5.14.2/Const/Fast.pm

    Modifying @INC with a different path:

    $ perl -Mstrict -Mwarnings -E ' unshift @INC => q{/Users/ken/perl5/perlbrew//perls/perl-5.14.2/lib/sit +e_perl/5.14.2}; require Const::Fast; shift @INC; say $Const::Fast::VERSION; say $INC{q{Const/Fast.pm}}; ' 0.008 /Users/ken/perl5/perlbrew//perls/perl-5.14.2/lib/site_perl/5.14.2/Cons +t/Fast.pm

    Note how I've put @INC back to the way it was with shift after each require.

    Choice of Const::Fast was completely arbitrary: I just happened to know I had different versions which was useful for demonstation purposes.

    -- Ken

Re: Picking up a module from a specific location
by srinigs (Novice) on Sep 11, 2012 at 08:20 UTC
    Thanks a lot for the replies, and I'm terribly sorry for the typo errors - I had used the right syntax in the code, made a mistake while typing it here (and it had still not worked for me). I tried whatever was suggested here, but in vain. Then i realised the problem is with "eval" - I believe since eval executes everything given to it as if it were a separate script, and since the code said " eval 'use P4' ", the changes to @INC or the "use lib" was not visible to it and was hence picking the old path itself. I changed " eval 'use P4' " to
    eval { use lib 'path2'; use P4; };
    and it started picking up the right path (path2) :)

    Cheers,
    srinigs

Re: Picking up a module from a specific location
by Anonymous Monk on Sep 11, 2012 at 07:06 UTC

    require "P4.pm"

    Why not  require P4;?

    I have specified "use lib path2" but it still always picks up the one at path1.

    This is not likely