2010-04-07 19 views
5

Sto trovando molto comodo per passare la configurazione e altri dati che vengono letti o calcolati una volta, ma poi utilizzati più volte in un programma utilizzando il meccanismo use di Perl. Lo sto facendo esportando un hash nello spazio dei nomi del chiamante. Per esempio:È buona pratica esportare variabili in Perl?

package Myconfiguration; 

my %config; 

sub import { 
    my $callpkg = caller(0); 
    my $expsym = $_[1]; 

    configure() unless %config; 

    *{"$callpkg\::$expsym"} = \%config; 
} 

e poi in altri moduli:

use MyConfiguration (loc_config_sym); 

if ($loc_config_sym{paramater}) { 
    # ... do stuff ... 
} 

Tuttavia, non sono sicuro di questo come una best practice. È meglio aggiungere un metodo che restituisca un hash ref con i dati? Qualcos'altro?

risposta

5

Se solo si desidera leggere i valori di %config, allora perché non avere una routine di farlo per tu?

my %config; 
sub config_value 
{ 
     my ($value) = @_; 
     return $config{$value}; 
} 

Si potrebbe esportare questo per difetto se si voleva:

package Mypackage; 
require Exporter; 
@EXPORT = qw/config_value/; 

La ragione per cui non avrei consentire l'accesso a l'hash in tutto il luogo in un sacco di diversi moduli è che avrei dovuto un periodo difficile tenendo mentalmente conto di tutti i posti in cui è stato utilizzato. Preferirei fare il tipo di accesso di cui sopra in modo tale che, se si verifica qualche errore, potrei aggiungere un'istruzione di stampa alla routine, o qualcosa del genere, per scoprire quando è stato effettuato l'accesso al valore. Non so se questo è collegato alle "migliori pratiche" o è solo perché sono stupido, ma il tipo di confusione creato dalle variabili globali mi spaventa.

Non c'è ragione per cui non si può avere un set di routine troppo:

sub set_value 
{ 
     my ($key, $value) = @_; 
     $config{$key} = $value; 
} 
+0

Questo è ciò che la scimmia nella mia testa stava cercando di dirmi, ma non ho potuto uscire (anche se preferisco 'usare Exporter qw (import);' :)). Non ho davvero pensato a questo come una variabile globale quando in pratica è esattamente quello che sto facendo qui. L'unico svantaggio è il sovraccarico della chiamata al metodo, ma non è probabile che sia importante, soprattutto considerando la manutenzione e il debug. Inoltre, è abbastanza facile alias il sub se è conveniente avere un nome localmente rilevante (non si tratta solo di configurazione). – gvkv

+0

Sono d'accordo che setter e getter sono la strada da percorrere. Ti danno molto più controllo. Ad esempio, puoi controllare il set di valori e fare il calcolo sul valore ottenuto. – Bill

2

Penso che sia meglio lavorare con una copia dell'hash di configurazione. In questo modo, se modifichi alcuni elementi, ciò non influirà sul resto del codice.

Io di solito uso l'oggetto semplice (facoltativamente Singleton) per questo con un singolo metodo come get_property().

+0

Questo particolare esempio era di configurazione, ma non è necessario. Ad esempio, potrei * volere * cambiare elementi. – gvkv

+0

È possibile modificare i valori in un singleton. –

0

In generale, è meglio consentire all'utente di decidere se importare o meno i simboli. Exporter rende tutto questo facile. Scrivere un metodo personalizzato import per consentire all'utente di decidere cosa denominare i simboli importati può essere utile in rare occasioni, ma non penso che questo sia uno di questi.

package MyConfiguration; 
require Exporter; 

our @ISA  = qw(Exporter); 
our @EXPORT_OK = qw(Config); 

our %Config; 

E poi, nello script:

use MyConfiguration; 
print $MyConfiguration::Config{key}; 

o

use MyConfiguration qw(Config); 
print $Config{key}; 
+3

Tranne che i documenti Exporter dicono esplicitamente: "Esportare variabili non è una buona idea, possono cambiare sotto la cappa, provocare effetti orribili a distanza, troppo difficili da rintracciare e riparare. esso ". Davvero, in questo caso, solo perché è possibile, non significa che sia una buona idea. –

2

Suggerisco di non esportare variabili. Creare una classe che può invece restituire un riferimento a una variabile privata. Le persone possono quindi memorizzarle in una variabile con il nome che preferiscono e solo quando decidono di volerlo utilizzare.

Problemi correlati