ProgrammationDéveloppeur Perl Senior

Parlez des particularités du travail avec la portée des variables en Perl. Quels sont les détails concernant les opérateurs my et local ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Perl, la portée des variables est définie par les mots-clés my et local.

  • my crée une variable avec une portée lexicale (elle n'est valable que dans le bloc actuel).
  • local sauvegarde temporairement la valeur actuelle d'une variable globale et fixe une nouvelle valeur pendant la durée du bloc — cela est souvent utilisé uniquement avec des variables globales (par exemple, $_, $/ etc.).

Exemple:

my $x = 42; # visible uniquement dans le bloc actuel { local $/ = undef; my $input = <STDIN>; # $/ ici est undef, après le bloc — cela restaurera la valeur }

Il est préférable d'utiliser my en raison d'une portée plus prévisible.

Question piège

Que se passe-t-il lorsque my et local sont utilisés avec la même variable, déclarée dans deux blocs différents ?

On répond souvent que local et my fonctionnent de la même manière, mais ce n'est pas le cas. local ne fonctionne qu'avec des variables globales (package variables). Une variable déclarée avec my n'est pas visible pour local.

Exemple:

our $foo = "global"; { local $foo = "local"; print $foo; # "local" } print $foo; # "global" { my $foo = "lexical"; } # $foo en dehors du bloc — version globale, pas "lexical"

Exemples d'erreurs réelles dues à l'incompréhension des subtilités du sujet


Histoire

Dans le script, local était utilisé pour remplacer temporairement une variable déclarée avec my, ce qui ne conduisait à aucun résultat et causait des bugs dans le traitement des événements dans l'un des modules internes.


Histoire

Dans le projet, $_ a été "localisé" via local à l'intérieur d'un foreach, en s'attendant à remplacer $_ pour les itérateurs, oubliant que foreach assigne déjà une nouvelle $_. Résultat — filtre non fonctionnel et logique de parcours incorrecte.


Histoire

La variable globale du package n'a pas été déclarée via our, et une tentative de localisation via local $var a conduit à l'échec du script à cause de strict et warning, et le débogage a duré une journée.