En Perl, il existe trois principaux types de déclaration de variables : my, our et state.
sub example_state { state $counter = 0; $counter++; return $counter; } for (1..3) { print example_state(), " "; # Affichera 1, puis 2, puis 3 }
Où utiliser correctement :
my — presque toujours le choix préféré pour les variables, sauf s'il y a une raison pour un accès global.our — pour exporter des variables entre les modules, lorsque le partage est nécessaire.state — lorsque la variable doit "se souvenir" de sa valeur entre les appels de fonction (par exemple, un compteur d'appels).Une variable déclarée avec our peut-elle être capturée dans une closure au même titre que my ?
On répond généralement "oui, c'est pratique", mais ce n'est pas vrai. La variable our est globale au package, et la closure ne lie pas sa valeur au moment de la création de la closure, mais accède via le nom global. Donc, sa "valeur" peut changer en dehors de la closure et affectera toutes les closures !
our $x = 10; my $closure = sub { return $x; }; $x = 42; print $closure->(); # Retournera 42, pas 10
Histoire
Dans un grand script de parsing de logs, les variables étaient déclarées via our pour "un accès pratique" depuis différentes fonctions du module. En conséquence, la modification de ces variables dans une fonction entraînait un comportement inattendu dans une autre, brisant le traitement parallèle des logs.
Histoire
L'utilisation de my pour des variables dont la valeur devait être conservée entre les appels de fonction (par exemple, un compteur dans un parcours récursif) entraînait la réinitialisation de la valeur à chaque appel, ce qui provoquait une logique de parcours incorrecte. Le remplacement par state a corrigé la situation.
Histoire
Une utilisation incorrecte de our dans un module importé (export de variables non via Exporter) a provoqué une collision de noms lors de l'importation de deux modules différents utilisant le même nom de variable. En fin de compte, les données "sautaient" d'un contexte à un autre.