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

mir*_*977 2 perl perl-module

我正在开发一个Perl脚本.在里面我用各种各样的moudules:

use Module::One;
use Module::Two;
...
Run Code Online (Sandbox Code Playgroud)

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

$GLOBAL_1 = 1;
$GLOBAL_2 = 1;
...
Run Code Online (Sandbox Code Playgroud)

假设脚本的名称是

my_script.pl
Run Code Online (Sandbox Code Playgroud)

是否有可能在向脚本传递一个名为'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;
    ...
}
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 7

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

所述示例在编译时工作,在这种情况下使用if pragma

use if @ARGV && ($ARGV[0] eq 'no_libs'), Module::One, qw(...);
Run Code Online (Sandbox Code Playgroud)

use Module::One qw(...)与条件为真有相同的效果.

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

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

应用可以归结为require因为use Module LIST;正好手段

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

所以你在运行时几乎一样.

但是,全局变量不能以这种方式导入,因为strict它们不会及时声明它们.感谢ikegami的评论.您可以直接作为使用它们$Module::One::Var,为our $VarModule::One,但请参阅下面的注释.

一般而言,从模块中导出全局变量并不是一个好习惯,因为它会侵蚀整体设计,通过纠缠所谓的不同组件并绕过它们的接口.它也可能导致细微且难以发现的问题.

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