我有一个 Perl 模块 (Module.pm),它初始化许多变量,我想将其中一些变量 ($VAR2、$VAR3) 导入到可能在执行期间加载的其他子模块中。
我目前设置Module.pm的方式如下:
package Module;
use warnings;
use strict;
use vars qw($SUBMODULES $VAR1 $VAR2 $VAR3);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($VAR2 $VAR3);
sub new {
my ($package) = @_;
my $self = {};
bless ($self, $package);
return $self;
}
sub SubModules1 {
my $self = shift;
if($SUBMODULES->{'1'}) { return $SUBMODULES->{'1'}; }
# Load & cache submodule
require Module::SubModule1;
$SUBMODULES->{'1'} = Module::SubModule1->new(@_);
return $SUBMODULES->{'1'};
}
sub SubModules2 {
my $self = shift;
if($SUBMODULES->{'2'}) { return $SUBMODULES->{'2'}; }
# Load & cache submodule
require Module::SubModule2;
$SUBMODULES->{'2'} = Module::SubModule2->new(@_);
return $SUBMODULES->{'2'};
}
每个子模块的结构如下:
package Module::SubModule1;
use warnings;
use strict;
use Carp;
use vars qw();
sub new {
my ($package) = @_;
my $self = {};
bless ($self, $package);
return $self;
}
我希望能够将 $VAR2 和 $VAR3 变量导入到每个子模块中,而不必将它们引用为 $Module::VAR2 和 $Module::VAR3。我注意到调用脚本能够以所需的方式访问我在 Module.pm 中导出的变量,但 SubModule1.pm 和 SubModule2.pm 仍然必须引用来自 Module.pm 的变量。
我尝试按如下方式更新每个子模块,不幸的是,我希望这不起作用:
package Module::SubModule1;
use warnings;
use strict;
use Carp;
use vars qw($VAR2 $VAR3);
sub new {
my ($package) = @_;
my $self = {};
bless ($self, $package);
$VAR2 = $Module::VAR2;
$VAR3 = $Module::VAR3;
return $self;
}
请告诉我如何成功地将 $VAR2 和 $VAR3 从 Module.pm 导出到每个子模块中。预先感谢您的帮助!
在你的子模块中,你是否忘记说
use Module;
?从另一个包调用
use Module
(例如 Module::Submodule9
)将尝试运行 Module::import
方法。由于您没有该方法,因此它将调用 Exporter::import
方法,这就是将 Module
的变量导出到 Module::Submodule9
命名空间的神奇之处。
在您的程序中只有一个
Module
命名空间和(全局)变量 $Module::VAR2
的一个实例。导出会在其他命名空间中创建该变量的别名,因此可以通过不同的方式访问同一变量。在单独的脚本中尝试一下:
package Whatever;
use Module;
use strict;
use vars qw($VAR2);
$Module::VAR2 = 5;
print $Whatever::VAR2; # should be 5.
$VAR2 = 14; # same as $Whatever::VAR2 = 14
print $Module::VAR2; # should be 14
有一个简单的方法:
下午:
package M;
use strict;
use warnings;
#our is better than "use vars" for creating package variables
#it creates an alias to $M::foo named $foo in the current lexical scope
our $foo = 5;
sub inM { print "$foo\n" }
1;
M/S.pm
package M;
#creates an alias to $M::foo that will last for the entire scope,
#in this case the entire file
our $foo;
package M::S;
use strict;
use warnings;
sub inMS { print "$foo\n" }
1;
在脚本中:
#!/usr/bin/perl
use strict;
use warnings;
use M;
use M::S;
M::inM();
M::S::inMS();
但我建议不要这样做。全局变量不是一个好的做法,在模块之间共享全局变量更糟糕。
这是来自“出口商(3pm)”下的“良好实践”:
导出变量不是一个好主意。它们可以在幕后发生变化,在远处引发可怕的影响,而这些影响很难追踪和修复。相信我:他们不值得。
为了提供设置/获取类范围设置的功能,最好 相反,以子例程或类方法的形式提供访问器。