Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: how to improve: use MODULE VERSION LIST

by smile4me (Beadle)
on Jan 07, 2017 at 19:29 UTC ( #1179142=note: print w/replies, xml ) Need Help??


in reply to Re: how to improve: use MODULE VERSION LIST
in thread how to improve: use MODULE VERSION LIST

Thanks kcott for the reply, I'll try to clarify:

Once the CTB folks have added a new feature, using a new or improved CPAN module, they certainly want it to go into production. Thus, they are willing to update the code to:

use autodie 2.29

Where I run into problem is that Perl does not find version 2.29 given the order of the default @INC. Remeber, the RTB folks are still looking for autodie 2.23 in the core perl paths when the interpreter was compiled; but, the CTB folks want to get the new one. Unfortunately, when compiling Perl with the otherlibdirs option (to include additional locations), it adds the new locations to the end of @INC.

So it seems, I am left with no other choice but to manipulate the @INC order in the code. Typically, once tools make their way into production, the owner (unix user) of scripts has a very limited shell environment (think apache user or www user). So relying on PERL5LIB, while okay for testing, is not so good for production.

Thus, your slicing the INC is an option. BTW, why is the '.' location not good in the @INC?

Smile
Steve

Replies are listed 'Best First'.
Re^3: how to improve: use MODULE VERSION LIST
by kcott (Bishop) on Jan 08, 2017 at 05:45 UTC

    Thanks for the clarifications. To be honest, it sounds like your problems are more political than technological. You probably need to implement a plan for upgrading software that's agreed to by all parties: probably involving rigorous testing, appropriate notifications, sign-offs at various levels and so on. I'll leave you to work on that. See also codiac's comments.

    Here's a suggestion that doesn't require altering @INC directly or via the lib pragma, nor does it rely on checking version numbers. (I've used version numbers in the examples below purely for identification purposes, the solution itself doesn't need them.)

    Some up-front information:

    $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -E' $ perl -v | head -2 | tail -1 This is perl 5, version 24, subversion 0 (v5.24.0) built for darwin-th +read-multi-2level

    Let's say you've got an xyz module. That's in production and lives in directory old. Here's old/xyz.pm:

    package xyz; our $VERSION = '1.0'; sub import { print "import called with args: @_\n"; } 1;

    You can use that with or without a VERSION; it might have a LIST, which could be empty.

    $ perle 'BEGIN { @INC = qw{old new .} } use xyz 1.0; say $xyz::VERSION +' import called with args: xyz 1.0 $ perle 'BEGIN { @INC = qw{old new .} } use xyz 1.0 (); say $xyz::VERS +ION' 1.0 $ perle 'BEGIN { @INC = qw{old new .} } use xyz 1.0 qw{a b c}; say $xy +z::VERSION' import called with args: xyz a b c 1.0 $ perle 'BEGIN { @INC = qw{old new .} } use xyz; say $xyz::VERSION' import called with args: xyz 1.0 $ perle 'BEGIN { @INC = qw{old new .} } use xyz (); say $xyz::VERSION' 1.0 $ perle 'BEGIN { @INC = qw{old new .} } use xyz qw{a b c}; say $xyz::V +ERSION' import called with args: xyz a b c 1.0

    Now, let's say that a new version of the xyz module becomes available. It has some features the developers want. You install it in directory new. Here's new/xyz.pm:

    package xyz; our $VERSION = '2.0'; sub import { print "import called with args: @_\n"; } 1;

    For the purposes of demonstration, that's identical to old/xyz.pm except for the version number. Attempting to use it by just specifying VERSION doesn't work because old/xyz.pm is found first in @INC (i.e. the problem already discussed).

    $ perle 'BEGIN { @INC = qw{old new .} } use xyz 2.0; say $xyz::VERSION +' xyz version 2 required--this is only version 1.0 at -e line 1. BEGIN failed--compilation aborted at -e line 1.

    What I suggest you do is create a new module that only needs to be very simple. I've called this Bleed::xyz and put it in the current directory (i.e. the last place in @INC to be searched). Here's ./Bleed/xyz.pm:

    package Bleed::xyz; our $VERSION = '2.0'; BEGIN { require 'new/xyz.pm'; } sub import { shift; xyz->import(@_); } 1;

    Now version 2.0 of xyz can be used with all the various combinations of VERSION and LIST.

    $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz 2.0; say $xyz:: +VERSION' import called with args: xyz 2.0 $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz 2.0 (); say $xy +z::VERSION' 2.0 $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz 2.0 qw{a b c}; +say $xyz::VERSION' import called with args: xyz a b c 2.0 $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz; say $xyz::VERS +ION' import called with args: xyz 2.0 $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz (); say $xyz::V +ERSION' 2.0 $ perle 'BEGIN { @INC = qw{old new .} } use Bleed::xyz qw{a b c}; say +$xyz::VERSION' import called with args: xyz a b c 2.0

    When version 2.0 of the xyz module is accepted into production, and assuming that involves moving new/xyz.pm to old/xyz.pm, you'll need one, very minor change to Bleed::xyz (i.e. s/new/old/). All existing code should continue to work. You can change instances of use Bleed::xyz to just use xyz at your leisure.

    "BTW, why is the '.' location not good in the @INC?"

    I didn't say that. I said:

    "... you end up with '.' at the front of the list: not a good idea.".

    Consider someone's who's bad. In /home/bad they write code with names like strict.pm, warnings.pm, autodie.pm, etc. that all do bad things. They then run your code from /home/bad. If @INC starts with '.', bad things will happen.

    — Ken

Re^3: how to improve: use MODULE VERSION LIST
by choroba (Archbishop) on Jan 07, 2017 at 22:40 UTC
    > Unfortunately, when compiling Perl with the otherlibdirs option (to include additional locations), it adds the new locations to the end of @INC.

    Prepending the locations to @INC wouldn't help, as the RTB folks wouldn't be able to load the old version anymore. When searching for a module, Perl checks the version only when it finds the first implementation. If the version is less than the one specified, Perl dies, it doesn't look for a different version in the rest of the paths.

    $ cat My.pm package My; our $VERSION = "1"; warn "1 loaded"; 1; $ cat 0/My.pm package My; our $VERSION = "2"; warn "2 loaded"; 1; $ perl -I. -I0 -e 'use My 1; warn $My::VERSION;' 1 loaded at My.pm line 2. 1 at -e line 1. $ perl -I0 -I. -e 'use My 1; warn $My::VERSION;' 2 loaded at 0/My.pm line 2. 2 at -e line 1. $ perl -I. -I0 -e 'use My 2; warn $My::VERSION;' 1 loaded at My.pm line 2. My version 2 required--this is only version 1 at -e line 1. BEGIN failed--compilation aborted at -e line 1. $?=255 $ perl -I0 -I. -e 'use My 2; warn $My::VERSION;' 2 loaded at 0/My.pm line 2. 2 at -e line 1. $ perl -I0 -I. -e 'use My 1; warn $My::VERSION;' 2 loaded at 0/My.pm line 2. 2 at -e line 1.

    But, interestingly

    $ perl -I. -I0 -e 'eval q{use My 2}; warn $My::VERSION;' 1 loaded at My.pm line 2. 1 at -e line 1.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2021-06-12 17:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)












    Results (53 votes). Check out past polls.

    Notices?