Domanda

Ho un modulo Perl (Module.pm) che inizializza una serie di variabili, alcune delle quali mi piacerebbe importazione ($ VAR 2, $ VAR3) in sottomoduli aggiuntivi che potrebbe caricare durante l'esecuzione.

Il modo in cui sto attualmente la creazione di Module.pm è la seguente:

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'};
}

Ogni modulo è strutturato come segue:

package Module::SubModule1;

use warnings;
use strict;
use Carp;

use vars qw();

sub new {
    my ($package) = @_;
    my $self = {};
    bless ($self, $package);
    return $self;
}

Voglio essere in grado di importare le variabili $ VAR 2 e $ var3 in ciascuno dei moduli senza doverli riferimento da $ Modulo :: VAR2 e $ Modulo :: VAR3. Ho notato che lo script chiamante è in grado di accedere sia le variabili che ho esportato in Module.pm nel modo desiderato, ma SubModule1.pm e SubModule2.pm devono ancora fare riferimento alle variabili come da Module.pm.

Ho provato ad aggiornare ogni modulo come segue che purtroppo non ha funzionato speravo:

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;
}

Per favore fatemi sapere come posso esportare con successo $ VAR2 e $ VAR3 da Module.pm in ogni sottomodulo. Grazie in anticipo per il vostro aiuto!

È stato utile?

Soluzione

Nei tuoi sottomoduli, stai dimenticando di dire

use Module;

? Chiamata use Module da un altro pacchetto (Module::Submodule9 diciamo) cercherà di eseguire il metodo Module::import. Dal momento che non si dispone di tale metodo, si chiamerà il metodo Exporter::import, ed è qui che la magia che le variabili esportazioni Module nel namespace Module::Submodule9 accadrà.


Nel programma c'è un solo Module spazio dei nomi e una sola istanza del (globale) variabile $Module::VAR2. L'esportazione crea alias per questa variabile in altri spazi dei nomi, quindi la stessa variabile può essere letta in modi diversi. Prova questo in uno script separato:

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

Altri suggerimenti

Beh, c'è il modo più semplice:

In M.pm:

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;

Nello script:

#!/usr/bin/perl

use strict;
use warnings;

use M;
use M::S;

M::inM();
M::S::inMS();

Ma vorrei consigliare contro questo. Le variabili globali non sono una buona pratica, e la condivisione di variabili globali tra i moduli è ancora peggio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top