Background: I have a perl module -- let's call it Foo::Common
which has been installed on one of our file servers (for the sake of simplicity, I will call thie the 'global' version). The module is included by somewhere on the order of 1000 perl scripts which are launched every 15 minutes. The module is several versions old, but Updating it is going to take a lot of testing over the course of several months.
I'm writing a new perl script which will run on the same processing server, but I need functionality which is only included in the most recent version of Foo::Common
. If I simply want to use the newer version of Foo::Common
, I can place Foo/Common.pm
in a ./lib
directory where the script is being run, then use the following code:
my $lib = '';
BEGIN {
$lib = $ENV{FOO_ENV_HOME} || '';
}
use lib "$lib/core/bin/";
use lib './lib';
use Foo::Common;
Because use lib
adds directories to the beginning of @INC
, the newer version of Foo::Common
will be found and used first.
This is all well and good, but I don't want my script dependent on the local version of Foo::Common
. The global version of Foo::Common
has our $VERSION = '1.1.2'
, and the version that I want to install locally is at 1.1.7
. If I deploy the code above, and then we upgrade the global version to the not-yet-written 1.2.0
, my script will be stuck running 1.1.7
.
According to perldoc -f require
:
`require $filename` Has semantics similar to the following subroutine:
sub require {
my ($filename) = @_;
if (exists $INC{$filename}) {
return 1 if $INC{$filename};
die "Compilation failed in require";
}
my ($realfilename,$result);
ITER: {
foreach $prefix (@INC) {
$realfilename = "$prefix/$filename";
if (-f $realfilename) {
$INC{$filename} = $realfilename;
$result = do $realfilename;
last ITER;
}
}
die "Can't find $filename in \@INC";
}
if ($@) {
$INC{$filename} = undef;
die $@;
} elsif (!$result) {
delete $INC{$filename};
die "$filename did not return true value";
} else {
return $result;
}
}
I'm not clear on how this interacts with the use MODULE VERSION
syntax, although discussion in the answer to What does Perl do when two versions of a module are installed? indicates that use Module Version
is not enough.
I presume that I'm going to manipulate @INC, but I'm not sure how to do that based on each module's $VERSION
, especially because use
has an implicit BEGIN
statement.
How do I approach this?