Historique de la question :
En Perl, les sous-programmes sont réalisés de manière très flexible depuis le début : tout appel de sous-programme peut accepter un nombre illimité de paramètres, qui sont placés dans le tableau @_. Cette approche convient aux tâches de différents niveaux de complexité et soutient la dynamique de Perl.
Problème :
De nombreux développeurs, en particulier les débutants, rencontrent de la confusion lors de l'utilisation de @_ — déstructuration incorrecte des paramètres, modification accidentelle des données d'entrée (puisque les variables sont passées par valeur et les structures complexes par référence), incohérence dans le nombre et les types d'arguments. Des problèmes surviennent lors du retour de différents types de données et lors de tentatives de mise en œuvre de prototypes de fonctions.
Solution :
Pour recevoir des arguments, le sous-programme doit explicitement les déstructurer à partir du tableau @_. Le retour de valeurs se fait par l'opérateur return, le comportement dépend du contexte (scalaire ou liste). Pour éviter les effets secondaires, les paramètres sont souvent acceptés par copie ou par référence, si des modifications au sein du sous-programme sont requises. Pour les structures complexes, on utilise le passage par référence.
Exemple de code :
sub add { my ($a, $b) = @_; return $a + $b; } sub change_array { my ($arr_ref) = @_; push @$arr_ref, 100; } my @nums = (1, 2, 3); my $sum = add(5, 10); change_array(\@nums); print join(", ", @nums); # 1, 2, 3, 100
Caractéristiques clés :
@_La fonction modifie-t-elle les paramètres qui lui sont passés si elle travaille avec des scalaires simples ?
Non, les scalaires sont copiés lors du passage, leurs modifications n'affectent pas l'original. Cependant, si l'argument est une référence, les données originales peuvent être modifiées.
Peut-on définir des valeurs par défaut pour les arguments des sous-programmes, comme dans d'autres langages ?
Pas directement. En Perl, il est nécessaire de réaliser soi-même la gestion des valeurs par défaut à l'intérieur du corps de la fonction, en utilisant les vérifications defined ou le nombre d'arguments.
Exemple de code :
sub foo { my ($arg1, $arg2) = @_; $arg2 //= 10; print "$arg1 $arg2 "; } foo(5); # 5 10
Que se passe-t-il lors d'un accès direct à @_ sans copie — par exemple, $a = $_[0] ?
Une telle attribution crée un alias : la modification de $a changera $_[0], et vice versa. Il est recommandé de créer des copies via my ($a) = @_; pour éviter des modifications inattendues.
** Cas négatif
Dans une fonction de traitement d'un tableau, on a oublié de copier les paramètres de @_ dans des variables locales. En conséquence, la modification de la variable locale a entraîné une modification du tableau original, provoquant des bugs dans d'autres parties du programme.
Avantages :
Inconvénients :
** Cas positif
Dans l'équipe, une pratique de déstructuration obligatoire de @_ au début de chaque sous-programme a été mise en œuvre, et de grands objets ne sont passés que par référence.
Avantages :
Inconvénients :