背景:我有一个perl模块 - 我们把它叫做Foo::Common
,它已经安装在我们的一个文件服务器上(为了简单起见,我将称之为'全局'版本)。该模块包含在每隔15分钟启动的1000个脚本的顺序中。该模块有几个版本,但更新它将在几个月内进行大量测试。如何根据模块版本有条件地更改@INC?
我正在写一个新的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
,我的脚本将停止运行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 ([email protected]) {
$INC{$filename} = undef;
die [email protected];
} elsif (!$result) {
delete $INC{$filename};
die "$filename did not return true value";
} else {
return $result;
}
}
我不是这个如何与use MODULE VERSION
语法交互清楚,虽然在回答What does Perl do when two versions of a module are installed?讨论表明use Module Version
是不够的。
我相信,我要去操纵@INC,但我不知道怎么做,基于每个模块的$VERSION
,特别是因为use
有一个隐BEGIN
声明。
我该如何解决这个问题?
不,不是很......我想用'$ ENV {} FOO_ENV_HOME /核心/斌/富/ Common.pm'当且仅当它是'$ VERSION'大于或等于到'./ lib/Foo/Common.pm'的'$ VERSION'。 –
如果我运行'eval {require Foo :: Common; };检查它是否为'$ VERSION',然后更改@INC并重新运行'eval {require Foo :: Common; };'如果之前的'$ VERSION'不够高? (我没有从Foo :: Common命名空间导出任何东西,所以我不需要*使用'use') –
执行这两个模块会导致问题,而这完全没有必要。 – ikegami