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

如何有条件地包含Perl模块和库,以及其中的全局变量,perl,perl-module,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

我正在开发一个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'.'
实际上代表更复杂的命令行参数处理,包括变量赋值等。然后,这种情况在运行时发生,您不能以这种方式对
进行条件设置,因为它在编译时运行

不过,前面提到的示例在编译时工作,在这种情况下,请使用

如果条件为真,则其效果与使用模块::一个qw(…)
相同

如果决策确实发生在运行时,那么您需要使用

由于<代码>使用模块列表,因此归结为<代码>要求表示完全正确

BEGIN{需要模块;模块->导入(列表);}

因此,您实际上是在运行时执行相同的操作

但是,全局变量不能以这种方式导入,因为
strict
不会及时进行声明。谢谢你的评论。您可以将它们直接用作
Module::One::Var
,用于
Module::One
中的
我们的$Var
,但请参见以下注释

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


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

确实存在,但有条件地加载导出没有意义的模块。有条件地加载导出变量的模块(并尝试使用这些变量)是正确的。(在正常情况下导出vars已经够糟糕的了。)@ikegami我以为
if
是在编译时执行的…?@zdim,“if”是指向“if”模块的链接(不是
if
语句)。@zdim,哦,对不起,我以为你指的是运行时执行的
if
语句。是,如果在编译时执行…,则使用
。这是模块应该加载的时间,所以这就是为什么这是一个很好的方法。@ikegami啊,好的。(否则,
use
be conditional?)我将它们的条件视为运行时(假设更复杂的命令行处理),尽管目前情况并非如此。
use if @ARGV && ($ARGV[0] eq 'no_libs'), Module::One, qw(...);
if ($no_libs) {
    require Module::One;
    Module::One->import( qw(f1 f2) );  # as in: use Module::One qw(f1 f2);
    ...
}