2010-04-07 16 views
5

Ich finde es sehr bequem, Konfiguration und andere Daten zu übergeben, die einmal gelesen oder berechnet werden, dann aber viele Male in einem Programm verwendet werden, indem man Perls use Mechanismus verwendet. Ich tue dies, indem ich einen Hash in den Namespace des Aufrufers exportiere. Zum Beispiel:Ist es eine gute Praxis, Variablen in Perl zu exportieren?

package Myconfiguration; 

my %config; 

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

    configure() unless %config; 

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

und dann in anderen Modulen:

use MyConfiguration (loc_config_sym); 

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

Allerdings bin ich über diese als Best Practice nicht sicher. Ist es besser, eine Methode hinzuzufügen, die einen Hash-Ref mit den Daten zurückgibt? Etwas anderes?

Antwort

5

Wenn Sie nur die Werte von %config lesen wollen, dann warum nicht eine Routine, es zu tun für Du?

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

Sie könnten dies standardmäßig exportieren, wenn man will:

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

Der Grund, dass ich keinen Zugriff auf die Hash überall in vielen verschiedenen Module ermöglichen, dass ich hätte, Es war eine schwere Zeit, alle Orte, an denen es benutzt wurde, im Auge zu behalten. Ich würde eher die obige Art von Zugriffsroutine machen, so dass, wenn ein Fehler passiert, ich eine Druckanweisung zu der Routine hinzufügen könnte, oder etwas, um herauszufinden, wann auf den Wert zugegriffen wurde. Ich weiß nicht, ob das mit "Best Practices" zu tun hat, oder nur, weil ich dumm bin, aber die Art von Verwirrung, die von globalen Variablen erzeugt wird, macht mir Angst.

Es gibt keinen Grund, warum Sie können nicht zu einer Reihe Routine:

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

Das ist, was der Affe in meinem Kopf versuchte, mir zu sagen, aber ich konnte nicht rauskommen (obwohl ich 'Exporteur qw (importieren) bevorzugen;' :)). Ich habe das nicht wirklich als globale Variable gesehen, wenn ich genau das hier mache. Der einzige Nachteil hier ist der Overhead des Methodenaufrufs, aber das ist wahrscheinlich nicht wichtig, insbesondere in Bezug auf Wartung und Debugging. Plus, es ist einfach genug Alias ​​das Sub, wenn es bequem ist, einen lokal relevanten Namen (das ist nicht nur über die Konfiguration). – gvkv

+0

Ich stimme zu, dass Setter und Getter der richtige Weg sind. Sie geben Ihnen viel mehr Kontrolle. Zum Beispiel können Sie die Wertemenge überprüfen und die Berechnung für den Wert get ausführen. – Bill

2

Ich denke, es ist besser, mit einer Kopie des Config-Hash zu arbeiten. Wenn Sie einige Elemente ändern, wirkt sich dies nicht auf den restlichen Code aus.

Normalerweise verwende ich einfache Objekt (optional Singleton) mit einer einzigen Methode wie get_property().

+0

Dieses spezielle Beispiel war eine der Konfiguration, aber es muss nicht sein. Das heißt, ich möchte möglicherweise Elemente ändern. – gvkv

+0

Sie können die Werte in einem Singleton ändern. –

0

Im Allgemeinen ist es am besten, den Benutzer entscheiden zu lassen, ob Symbole importiert werden sollen oder nicht. Exporter macht dies einfach. Das Schreiben einer benutzerdefinierten import-Methode, mit der der Benutzer entscheiden kann, wie importierte Symbole benannt werden, kann in seltenen Fällen nützlich sein, aber ich denke nicht, dass dies einer davon ist.

package MyConfiguration; 
require Exporter; 

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

our %Config; 

Und dann, in Ihrem Skript:

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

oder

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

Außer der Exporter-Dokumentation heißt es ausdrücklich: "Das Exportieren von Variablen ist keine gute Idee. Sie können sich unter der Haube verändern und schreckliche Effekte aus der Ferne hervorrufen, die zu schwer zu verfolgen und zu beheben sind. Vertraue mir: sie sind es nicht wert es." Wirklich, in diesem Fall, nur weil du kannst, bedeutet es nicht, dass es eine gute Idee ist. –

2

ich nie Variablen Export vor. Erstellen Sie eine Klasse, die stattdessen einen Verweis auf eine private Variable zurückgeben kann. Die Leute können sie dann in einer Variablen mit dem Namen speichern, den sie mögen, und nur dann, wenn sie sich entscheiden, sie zu benutzen.

Verwandte Themen