Perl, импортирующий переменные из вызывающего модуля - PullRequest
0 голосов
/ 01 сентября 2010

У меня есть модуль 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 в каждый подмодуль. Заранее спасибо за помощь!

Ответы [ 2 ]

5 голосов
/ 01 сентября 2010

В своих подмодулях вы забыли сказать

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
0 голосов
/ 01 сентября 2010

Ну, есть простой способ:

В часах вечера ::1003*

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();

Но я бы посоветовал против этого. Глобальные переменные не являются хорошей практикой, а разделение глобальных переменных между модулями еще хуже.

...