In Perl gibt es drei Haupttypen von Variablendeklarationen: my, our und state.
sub example_state { state $counter = 0; $counter++; return $counter; } for (1..3) { print example_state(), " "; # Gibt zuerst 1, dann 2, dann 3 aus }
Wo man sie richtig verwenden sollte:
my — fast immer die bevorzugte Wahl für Variablen, wenn es keinen Grund für globalen Zugriff gibt.our — zum Exportieren von Variablen zwischen Modulen, wenn gemeinsames Teilen erforderlich ist.state — wenn die Variable "merken" soll, was zwischen Funktionsaufrufen (z.B. Zähler für Aufrufe) passiert.Kann eine mit our deklarierte Variable in einem Closure aufgenommen (captured) werden, wie bei my?
Normalerweise antworten die Leute „ja, das ist praktisch“, aber das ist nicht der Fall. Eine our Variable ist global im Paket, und ein Closure bindet im Grunde ihren Wert nicht zum Zeitpunkt der Erstellung, sondern greift über den globalen Namen darauf zu. Daher kann sich ihr "Wert" von außen ändern und alle Closures betreffen!
our $x = 10; my $closure = sub { return $x; }; $x = 42; print $closure->(); # Gibt 42 zurück, nicht 10
Geschichte
In einem großen Log-Parsing-Skript wurden Variablen über our deklariert, um "bequem darauf zuzugreifen" aus verschiedenen Funktionen des Moduls. In der Folge führte eine Änderung dieser Variablen in einer Funktion zu unerwartetem Verhalten in einer anderen und brach die parallele Log-Verarbeitung.
Geschichte
Die Verwendung von my für Variablen, deren Wert zwischen den Aufrufen einer Funktion (z.B. Zähler innerhalb einer rekursiven Durchlauf) gespeichert werden sollte, führte dazu, dass der Wert bei jedem Aufruf zurückgesetzt wurde, was zu einer fehlerhaften Logik des Durchlaufs führte. Der Austausch gegen state behob das Problem.
Geschichte
Falsche Verwendung von our in einem importierten Modul (Exportieren von Variablen nicht über Exporter) führte zu Namenskollisionen beim Einbinden von zwei verschiedenen Modulen, die denselben Variablennamen verwendeten. Letztendlich „sprangen“ die Daten von einem Kontext in einen anderen.