Historique de la question :
Les tranches (slices) sont une caractéristique puissante de Perl, permettant d'extraire ou d'assigner immédiatement un groupe d'éléments d'un tableau ou d'un hachage en une seule opération. Le mécanisme des tranches existe presque depuis les premières versions de Perl, supporte une syntaxe similaire à celle de Python, mais possède ses propres particularités d'exécution et de contexte.
Problème :
La principale difficulté avec les tranches : distinguer les tranches-liste des tableaux et des hachages, leur contexte scalaire/liste, les nuances « fines » lors de l'assignation via une tranche (surtout si l'assignation se fait vers les mêmes tableaux ou hachages, ou si des indices répétés sont utilisés). Un point important : si vous mettez à jour la structure avec des tranches, il est facile d'obtenir par inadvertance un résultat non évident en raison de l'expansion automatique de la liste.
Solution :
Utilisez des tranches uniquement de manière consciente. Si vous avez besoin de faire une copie des données, utilisez un clonage explicite de la liste. Évitez les chevauchements lors de la lecture et de l'écriture, et surveillez explicitement le contexte scalaire/liste si la tranche est utilisée comme argument de fonction ou élément dans une expression.
Exemple de code :
my @array = (10, 20, 30, 40, 50); my @slice = @array[1, 3]; # (20, 40) @array[0, 2] = (100, 300); # @array est maintenant (100, 20, 300, 40, 50) my %hash = (foo => 1, bar => 2, baz => 3); my @vals = @hash{"foo", "baz"}; # (1, 3)
Caractéristiques clés :
Question piège 1 : Peut-on obtenir une valeur "scalaire" d'une tranche @array[2, 4] comme $val = @array[2, 4] ?
Non, $val sera dans ce cas égal au nombre d'éléments (longueur de la liste), et non à la valeur d'un seul élément. Il est correct d'accéder à des éléments individuels uniquement via des indices uniques : $array[2].
Question piège 2 : Que se passe-t-il si la tranche a des indices répétitifs ?
Réassignement successif : chaque assignation est effectuée pour chaque indice de gauche à droite, le dernier l'emporte. Par exemple :
@array[0,0] = (1,2); # $array[0] == 2
Question piège 3 : Peut-on assigner des tranches avec un nombre différent d'éléments à droite et à gauche ?
Oui, si à droite, il y a moins d'éléments, les restants recevront undef. S'il y en a plus, les excédents sont ignorés. C'est généralement une source d'erreurs difficiles à détecter.
Un développeur assigne des valeurs : @array[2, 3] = ("foo");
Il s'attendait à ce que les deux éléments reçoivent "foo", mais $array[3] est devenu undef.
Avantages :
Inconvénients :
Utilise la fonction map pour mapper les valeurs : @array[2, 3] = map { "foo" } (2, 3);
Avantages :
Inconvénients :