Domanda

Ho un file revs.pm:

my %vers = ( foo => "bar" );

E un altro file come importer.pl:

use revs;

Come posso accedere %vers da importer.pl?

È stato utile?

Soluzione

Creare un modulo corretto e cambiare il mia parola chiave per la nostra :

# revs.pm
package revs;

our %vers = ( foo => "bar" );

1; # Perl modules need to return a boolean "true" value.

# importer.pl
use revs;

print $revs::vers{foo} . "\n";

Altri suggerimenti

Un altro modo convenzionale è quello di utilizzare la esportatore modulo nel pacchetto , ed esportare la variabile:

package revs;
use strict;
use warnings;
require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(%vers);
our %vers   = (foo=>'bar');
1;

Questo evita di dover utilizzare il nome del pacchetto quando si fa riferimento alla variabile da importer.pl:

use strict;
use warnings;
use Data::Dumper;
use revs;
print Dumper(\%vers);

Uno svantaggio è che è necessario assicurarsi che il nome della variabile è unico, al fine di evitare collisioni di nomi.

In alternativa, si potrebbe parti proprio non paio di vostro programma con variabile globale. Pensate a cosa succede quando si utilizza questa hash in un unico modulo:

package Foo;
use MyApp::Versions qw(%versions); # i'm going to pretend that you didn't call the module "revs".

some_function {
    while(my ($k, $v) = each %versions){
       return if $some_condition;
    }
}

E poi in qualche altro modulo:

package Bar;
use MyApp::Versions qw(%versions);

some_other_function {
    while(my ($k, $v) = each %versions){
       print "$k => $v\n";
    }
}

e quindi utilizzare entrambi i moduli:

use Foo;
use Bar;

some_other_function;
some_function;
some_other_function;

A seconda $some_condition, some_other_function produce diversi risultati ogni volta che si chiama. Buon divertimento debug che. (Questo è più di un problema di each di un problema di stato globale; ma esponendo l'implementazione interna, si consente ai chiamanti di fare cose che non si intendeva, e che può facilmente rompere il vostro programma.)

E 'anche un dolore per riscrivere Foo e bar quando si cambia il codificato duro hash ad una ricerca nel database on-demand, per esempio.

Quindi, la vera soluzione è quella di progettare un'API corretta, e che l'esportazione anziché l'intera variabile:

package MyApp::Versions;
use strict;
use Carp qw(confess);
use Sub::Exporter -setup => {
    exports => ['get_component_version'],
};

my %component_versions = ( foo => 42 ); # yes, "my", not "our".

sub get_component_version {
    my ($component) = @_;
    return $component_versions{$component} ||
        confess "No component $component!"
}

1;

Ora il modulo è più facile da usare:

package Foo;
use MyApp::Versions qw(get_component_version);

sub some_function {
    die 'your foo is too old'
        unless get_component_version('foo') >= 69;

    return FooComponent->oh_hai;
}

Ora una_qualche_funzione non può rovinare some_other_function, e quando modificare l'implementazione del get_component_version, il resto della tua il programma non si cura.

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