如何有条件地包含 Perl 模块和库,以及它们的全局变量

How to include conditionally Perl modules and libraries, as well as Global variables from them

我正在开发 Perl 脚本。在里面我使用了各种模块:

use Module::One;
use Module::Two;
...

我还使用这些模块中的全局变量:

$GLOBAL_1 = 1;
$GLOBAL_2 = 1;
...

假设脚本的名称是

my_script.pl

是否可以在向脚本传递名为 'no_libs' 的参数时有条件地包含上述模块和全局变量,但无论何时不传递此参数 - 不包含或使用它们? 类似的东西:

perl my_cript.pl no_libs

if ( $ARGV[0] eq 'no_libs' ) {
    use Module::One;
    use Module::Two;
    ...

    $GLOBAL_1 = 1;
    $GLOBAL_2 = 1;
    ...
}

我希望示例 $ARGV[0] eq '...' 真正代表对命令行参数的更多复杂处理,包括对变量的赋值等。然后这会在运行时发生,你不能以这种方式调节 use,因为它在编译时运行。

虽然所述示例在编译时有效,但在这种情况下使用 if pragma

use if @ARGV && ($ARGV[0] eq 'no_libs'), "Module::One", qw(...);

如果条件为真,与use Module::One qw(...)效果相同。

如果决定确实发生在运行时,那么您需要使用 require 而不是

if ($no_libs) {
    require Module::One;
    Module::One->import( qw(f1 f2) );  # as in: use Module::One qw(f1 f2);
    ...
}

use 归结为 require,因为 use Module LIST; 正好意味着

BEGIN { require Module; Module->import( LIST ); }

所以你在做几乎相同的事情,但在运行时。

但是,全局变量无法以这种方式导入,因为 strict 无法及时声明。感谢 ikegami 的评论。可以直接用$Module::One::Var,for our $Var in Module::One,不过请看下面的评论。

一般来说,从模块中导出全局变量并不是一个好的做法,因为它会通过缠绕理应不同的组件并绕过它们的接口来侵蚀整体设计。它还可能导致微妙且难以检测的问题。

有条件地全局变量似乎很奇怪:如果它们可能不存在,你如何使用它们?这可能是一个令人困惑的设计,可能会被更改。