ProgrammationDéveloppeur Full Stack Perl

Quels sont les méthodes de passage des arguments dans les sous-programmes Perl et comment organiser le passage par référence ? Quelles sont les subtilités du travail avec @_ et quand le passage par référence est-il nécessaire ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Perl, tous les arguments de fonction passent par le tableau @_. Lors de l'appel d'un sous-programme, tous les paramètres transmis se retrouvent à l'intérieur de ce tableau, et au départ — c'est une liste, pas une copie, c'est-à-dire que si vous changez $_[0], vous modifiez l'original.

Passage par valeur :

sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Seule la variable locale change }

Passage par référence :

sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data est maintenant (1,2,3,42)

Subtilités :

  • Si vous souhaitez modifier le tableau ou le hachage original — passez une référence.
  • Les variables ordinaires ($foo, $bar) à l'intérieur de @_ sont des alias des arguments originaux, mais lors du déballage via my ($a, $b) = @_, des copies sont créées.
  • Pour les tableaux et les hachages, lors du passage normal, leur contenu est déplié en liste, et vous perdrez les frontières : il faut passer une référence ou utiliser la spécificité des décalages.

Une question piégée

Si vous passez un tableau à une fonction en Perl comme ceci : myfunc(@arr), et que vous accédez à $_[0] à l'intérieur de la fonction, que trouvera-t-on ?

Réponse correcte : Il y aura le premier élément de la valeur du tableau, et non une référence à tout le tableau ! Pour passer un tableau comme un objet unique, utilisez une référence : myfunc(\@arr).

Exemple :

sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Affichera 'foo', pas une référence au tableau print_first(\@a); # Affichera ARRAY(0x...) — référence à tout le tableau

Histoire

Dans un des projets de modification d'un hachage global, on appelait la fonction comme ceci : update_hash(%global). À l'intérieur, $_[0] était modifié. En conséquence — seul un segment local du tableau d'arguments était modifié, et le hachage global n’était pas modifié. La solution correcte était de passer une référence : update_hash(\%global).

Histoire

En écrivant un cadre API, les fonctions recevaient de nombreux arguments nommés en utilisant un hachage. Parfois, un tableau (mais pas une référence !) était passé à la fonction, et les arguments "se mélangeaient", ce qui causait de la confusion : myfunc(@arr, %opts). Il s'est avéré qu'une partie des clés du hachage était remplacée par les valeurs du tableau, et il était difficile de détecter l'erreur.

Histoire

Lors de la mise en œuvre d'un parcours récursif d'un arbre, nous souhaitions modifier les éléments internes. Les tableaux étaient passés "tel quel" à la fonction, pas par référence. Ils créaient des copies, les modifications n'avaient aucun impact sur le contexte externe. Le problème a été résolu en remplaçant les passages par un style de référence.