gpt4 book ai didi

perl - 如何根据模块版本有条件地更改@INC?

转载 作者:行者123 更新时间:2023-12-02 08:45:36 24 4
gpt4 key购买 nike

背景:我有一个 perl 模块——我们称它为 Foo::Common,它已安装在我们的一个文件服务器上(为了简单起见,我将其称为“全局” ' 版本)。该模块包含在每 15 分钟启动一次的大约 1000 个 perl 脚本的某个位置。该模块有几个旧版本,但更新它需要在几个月的时间里进行大量测试。

我正在编写一个将在同一处理服务器上运行的新 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 ($@) {
$INC{$filename} = undef;
die $@;
} 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 语句。

我该如何处理?

最佳答案

太阳底下并无新鲜事。

use <a href="http://search.cpan.org/perldoc?only%3a%3alatest" rel="noreferrer noopener nofollow">only::latest</a> 'Foo::Common'

关于perl - 如何根据模块版本有条件地更改@INC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12714032/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com