背景:我有一个 perl 模块——我们称它为Foo::Common
已安装在我们的一个文件服务器上(为简单起见,我将其称为“全局”版本)。该模块包含在大约 1000 个 perl 脚本中,每 15 分钟启动一次。该模块有几个旧版本,但更新它需要几个月的时间进行大量测试。
我正在编写一个新的 perl 脚本,它将在同一处理服务器上运行,但我需要仅包含在最新版本的Foo::Common
. 如果我只是想使用较新版本的Foo::Common
,我可以将其放在正在运行脚本Foo/Common.pm
的目录中,然后使用以下代码:./lib
my $lib = '';
BEGIN {
$lib = $ENV{FOO_ENV_HOME} || '';
}
use lib "$lib/core/bin/";
use lib './lib';
use Foo::Common;
因为use lib
将目录添加到 的开头,所以将首先找到并使用@INC
较新版本的。Foo::Common
这一切都很好,但我不希望我的脚本依赖于本地版本的Foo::Common
. 全局版本Foo::Common
有our $VERSION = '1.1.2'
,我要本地安装的版本是1.1.7
。如果我部署上面的代码,然后我们将全局版本升级到尚未编写的1.2.0
,我的脚本会卡在 running 1.1.7
。
根据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;
}
}
我不清楚这如何与use MODULE VERSION
语法交互,尽管在安装两个版本的模块时 Perl 会做什么的答案中进行了讨论?表示use Module Version
还不够。
我假设我要操作@INC,但我不确定如何根据每个模块的来执行此操作$VERSION
,特别是因为use
有一个隐式BEGIN
声明。
我该如何处理?