Historique de la question :
Dans Perl, on peut limiter la portée des variables par les opérateurs my (visibilité lexicale) et local (réaffectation temporaire dynamique). local est largement utilisé pour redéfinir des variables globales et des descripteurs spéciaux (comme $_, $/, $@, %ENV).
Problème :
Le principal problème est la confusion entre la portée dynamique et lexicale. local ne crée pas une nouvelle variable, mais remplace temporairement la valeur d'une variable globale (ou de package) pendant l'exécution du bloc. Cela est particulièrement critique lors de la réaffectation de telles variables que $/ (séparateur de lignes), $_ (variable par défaut), $^W (drapeau d'avertissement), %ENV, STDIN/STDOUT.
Solution :
Exemple de code :
our $Global = "Hello!"; sub change1 { my $Global = "Bye!"; print "$Global "; } sub change2 { local $Global = "Bye!"; print "$Global "; } print "$Global "; # Hello! change1(); # Bye! print "$Global "; # Hello! change2(); # Bye! print "$Global "; # Hello!
Caractéristiques clés :
Est-ce que local peut s'appliquer aux variables lexicales déclarées avec my ?
Non, local ne fonctionne qu'avec des variables globales de package. Il est impuissant sur les objets my.
Que se passe-t-il lorsque local est appliqué à des descripteurs spéciaux, par exemple, STDIN ?
On peut temporairement redéfinir STDIN/STDOUT/stdin via local, par exemple, pour remplacer le flux d'entrée/sortie dans une sous-programme sans effet global. Après la sortie du bloc, le handle sera restauré.
Quelle est la différence critique entre local et my lors d'appels récursifs de fonctions ?
local fournit une pile de valeurs "push/pop" — chaque appel redéfinit temporairement la valeur du package, et les appels imbriqués obtiennent cette valeur redéfinie. my fournit une seule valeur lexicale dans le cadre du bloc sans héritage à l'intérieur.
Dans un test, on utilise local pour remplacer %ENV, après la sortie du bloc, des effets secondaires inattendus se produisent dans d'autres threads, car le code est multithreadé et local a été appliqué de manière inappropriée.
Avantages :
Inconvénients :
On remplace des variables spéciales ($/, $@, $SIG) uniquement pendant le temps d'appel du bloc nécessaire, après quoi les modifications sont correctement annulées.
Avantages :
Inconvénients :