In Perl zijn er drie hoofdtypen variabelenverklaring: my, our en state.
sub example_state { state $counter = 0; $counter++; return $counter; } for (1..3) { print example_state(), " "; # Geeft 1, dan 2, dan 3 }
Waar correct te gebruiken:
my — bijna altijd de voorkeur voor variabelen, tenzij er een reden is voor globale toegang.our — voor het exporteren van variabelen tussen modules, wanneer gedeeld gebruik vereist is.state — als de variabele een waarde moet "onthouden" tussen aanroepen van de functie (bijvoorbeeld, een aanroep teller).Kan een variabele die met our is gedeclareerd, worden vastgelegd (captured) in een closure zoals my?
Meestal antwoorden mensen "ja, dat is handig", maar dat is niet waar. Een our variabele is globaal voor het pakket, en een closure bindt haar waarde op het moment van creatie niet, maar benadert deze via de globale naam. Daarom kan haar "waarde" van buiten de closure veranderen, wat alle closures beïnvloedt!
our $x = 10; my $closure = sub { return $x; }; $x = 42; print $closure->(); # Geeft 42 terug, niet 10
Verhaal
In een groot script voor log parsing werden variabelen gedeclareerd met our voor "gemakkelijke toegang" vanuit verschillende functies van het module. Als gevolg daarvan leidde het wijzigen van deze variabelen in één functie tot onverwacht gedrag in een andere, wat de parallelle verwerking van logs verstoorde.
Verhaal
Het gebruik van my voor variabelen waarvan de waarde moest worden onthouden tussen aanroepen van de functie (bijvoorbeeld, een teller binnen een recursieve doorloop) leidde tot het resetten van de waarde bij elke oproep, wat leidde tot onjuiste doorlooplogica. Vervangen door state loste het probleem op.
Verhaal
Onjuist gebruik van our in een geïmporteerd module (export van variabelen niet via Exporter) leidde tot naamconflicten bij het opnemen van twee verschillende modules die dezelfde variabelenaam gebruikten. Hierdoor "sprongen" gegevens van de ene context naar de andere.