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

标签 perl module

背景:我有一个 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/

相关文章:

perl - 在 Devel::Cover 报告中包含未发现的文件

module - Ansible playbook 阻止所有 IP 排除一个或多个 IP

javascript - 我怎样才能使这个对象模式发挥作用?

python - 如何使用 pycogent 在 python 2.7 中创建祖先序列?

haskell - 如何使用实例组织 Haskell 模块 : stick to data type vs type class?

python - -m 开关的目的是什么?

Perl:常量和编译时与运行时哈希查找?

perl - "First steps with PDL"使用 Gnuplot 创建的图像与 PDL Book 中的图像不同

perl - 读取文件和执行文件一样危险吗

perl - 无法使用 perl 模块 HTTP::Request::Generator 传递自定义 header