Perl Импортирующие переменные от модуля вызова
-
26-09-2019 - |
Вопрос
У меня есть модуль Perl (Module.pm), который инициализирует ряд переменных, некоторые из которых я хотел бы импортировать ($ var2, $ var3) в дополнительные подмодулы, которые он может загружаться во время выполнения.
То, как в настоящее время настраивая модуль .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 в каждую из подмодулей без необходимости ссылаться на них как $ модуль :: var2 и $ module :: var3. Я заметил, что вызывающий скрипт способен получить доступ как на обоих переменных, которые я экспортировал в Module.pm в нужную моду, но подмодулю1.PM и DRUMODULE2.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
пространство имен и только один экземпляр (Global) переменной $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;
В м / с.пм
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();
Но я бы посоветовал против этого. Глобальные переменные - не очень хорошая практика, и совместное использование глобальных переменных между модулями еще хуже.