In Perl ci sono tre tipi principali di dichiarazione delle variabili: my, our e state.
sub example_state { state $counter = 0; $counter++; return $counter; } for (1..3) { print example_state(), " "; # Restituisce 1, poi 2, poi 3 }
Dove usarle correttamente:
my — è quasi sempre la scelta preferita per le variabili, se non ci sono motivi per un accesso globale.our — per esportare variabili tra i moduli, quando è necessario un uso condiviso.state — nel caso in cui la variabile debba "ricordare" un valore tra le chiamate di funzione (ad esempio, un contatore di chiamate).Può una variabile dichiarata con our essere catturata (captured) in una chiusura come my?
Di solito si risponde "sì, è conveniente", ma non è così. La variabile our è globale per il pacchetto, e la chiusura non sta legando il suo valore al momento della creazione della chiusura, ma accedendo attraverso il nome globale. Pertanto, il suo "valore" può cambiare esternamente alla chiusura e influenzare tutte le chiusure!
our $x = 10; my $closure = sub { return $x; }; $x = 42; print $closure->(); # Restituisce 42, non 10
Storia
In un grande script per il parsing dei log, le variabili venivano dichiarate tramite our per "accesso conveniente" da diverse funzioni del modulo. Di conseguenza, la modifica di queste variabili in una funzione portava a comportamenti inaspettati in un'altra, rompendo l'elaborazione parallela dei log.
Storia
L'uso di my per variabili di cui era necessario mantenere il valore tra le chiamate di funzione (ad esempio, un contatore all'interno di una traversata ricorsiva) portava al reset del valore ad ogni chiamata, causando una logica di traversata errata. Sostituirlo con state ha risolto la situazione.
Storia
L'uso scorretto di our in un modulo importato (esportazione di variabili non tramite Exporter) ha causato collisione di nomi durante il caricamento di due moduli diversi che usavano lo stesso nome di variabile. Di conseguenza, i dati "saltavano" da un contesto all'altro.