【问题标题】:How do I dynamically change the Perl module path?如何动态更改 Perl 模块路径?
【发布时间】:2011-01-11 20:24:51
【问题描述】:

我有两个不同版本的 Perl 模块。目前,关键脚本使用环境变量指定的模块版本,系统依赖于不同用户运行的不同任务。用户的环境将决定使用哪个版本的 Perl 模块。

现在我想将其更改为在 Perl 脚本中指定的版本,即取决于传递的选项。不幸的是,像这样的代码:

if ($new){ use lib "newdir"; }
else{ use lib "olddir"; }
use module;

不起作用。 Perl 只需将 newdirolddir 附加到@INC,然后运行脚本。

如何动态指定要使用的模块?

【问题讨论】:

    标签: perl module


    【解决方案1】:

    您需要使用BEGIN{} 块,以便您的if-else 代码将在编译时运行:

    BEGIN {
        if ($new) { unshift @INC, "newdir"; }
        else {      unshift @INC, "olddir"; }
    }
    use module;
    

    您还可以设置PERL5LIB 环境变量,这样您就不必在脚本中进行此类配置。

    【讨论】:

    • 你的奇怪包围风格给你留下了一个未闭合的块。 (现在,开始一场包围战!)
    • 另外值得一提的是,“使用lib”和直接操作@INC 并不总是等价的操作。有关详细信息,请参阅文档。
    【解决方案2】:

    CPAN 上有一个 only 编译指示,可以轻松安装和使用同一模块的多个版本。

    【讨论】:

      【解决方案3】:

      如果您希望您的逻辑在运行时发生(例如,如果 $new 变量以某种更复杂的方式生成,您不想在 BEGIN 块中运行),您可以使用 require() 加载模块在运行时。

      要记住的重要一点是

      use Module;
      use ModuleWithExports qw(export1 export2);
      

      是一样的

      BEGIN { require Module; Module->import() }
      BEGIN {
          require ModuleWithExports;
          ModuleWithExports->import('export1', 'export2');
      }
      

      这意味着要让您的代码在运行时运行,您只需:

      if ($new) {
          unshift @INC, "newdir";
      }
      else {
          unshift @INC, "olddir";
      }
      require module;
      module->import(); # if necessary
      

      使用 require() 的替代方法是使用 CPAN 中的 Module::Load 模块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-05
        • 2020-09-24
        • 2015-03-17
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        • 2015-03-30
        相关资源
        最近更新 更多