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

时间:2018-06-27 05:39:55

标签: perl perl-module

我正在开发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;
    ...
}

1 个答案:

答案 0 :(得分:6)

我希望示例$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的{​​{1}}中的our $Var,但请参阅以下注释。

通常,从模块中导出全局变量不是一个好习惯,因为它会纠缠据说不同的组件并绕过它们的接口,从而破坏了总体设计。它还可能导致难以发现的问题。

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