En Perl, il n’existe pas de syntaxe intégrée pour les tableaux multidimensionnels, comme cela est le cas dans certains autres langages. À la place, on utilise des tableaux de tableaux, où chaque élément de premier niveau est une référence à un autre tableau. Cette organisation permet de modéliser de manière flexible des tableaux, des matrices et d'autres structures de données nécessitant une dimensionnalité ou une plus grande imbrication.
Initialement, Perl a été développé pour le traitement de texte et le travail avec des structures simples, mais avec l'apparition des références (à partir de Perl 5), les développeurs ont pu construire des structures imbriquées complexes, par exemple, des tableaux de tableaux ou des hachages de tableaux.
Le principal malentendu chez les nouveaux utilisateurs est la tentative de créer un tableau à deux dimensions de manière simple, par exemple en déclarant @matrix = ( (1,2), (3,4) ). Cette approche ne donnera pas le résultat voulu, car les éléments seront décompressés comme des valeurs scalaires, et non comme des structures imbriquées. On commet également souvent une erreur lors de la copie des tableaux : une copie non approfondie entraîne des effets secondaires inattendus.
En Perl, les tableaux multidimensionnels sont construits à travers des références à des tableaux. L'initialisation correcte est la suivante :
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } # Accès à l'élément : $matrix[1][2]
Ou via des références anonymes :
my $matrix = [ [1,2,3], [4,5,6], [7,8,9] ]; print $matrix->[1][2]; # 6
Caractéristiques clés :
Peut-on créer des tableaux multidimensionnels sans références, simplement en déclarant des parenthèses à l'intérieur des parenthèses, comme dans d'autres langages ?
Non. Dans ce cas, Perl décompresse les éléments comme une liste ordinaire. Seule l'utilisation de références est correcte.
Exemple de code incorrect :
my @matrix = ((1,2,3),(4,5,6),(7,8,9)); # Les éléments sont en ligne print $matrix[3]; # 4, et non [4,5,6] — opération incorrecte
Méthode correcte :
my @matrix = ( [1,2,3], [4,5,6], [7,8,9] ); print $matrix[1][2]; # 6
Que se passe-t-il si l’on copie un tableau de tableaux avec une simple affectation ?
Seul le premier niveau est copié, les tableaux imbriqués feront référence aux mêmes zones de mémoire.
Exemple :
my @a = ( [1,2], [3,4] ); my @b = @a; $a[0][0] = 99; print $b[0][0]; # 99, alors que l'on s'attendait à 1 — copie non profonde !
Peut-on copier "profondément" un tableau imbriqué avec les outils intégrés de Perl ?
Non, Perl ne fournit pas d'opérateur standard pour une copie profonde des structures imbriquées. Il faut utiliser le module Storable ou une fonction récursive.
Exemple avec Storable :
use Storable 'dclone'; my $deepcopy = dclone(\@matrix);
Un développeur crée une matrice à deux dimensions avec une simple déclaration de tableau et la copie avec une affectation :
my @m1 = ([1,2],[3,4]);
my @m2 = @m1;
$m1[0][0] = 77;
print $m2[0][0];
Avantages :
Inconvénients :
Utilisation du module Storable pour une copie profonde :
use Storable 'dclone'; my @m1 = ([1,2],[3,4]); my $m2 = dclone(\@m1); $m1[0][0] = 77; print $m2->[0][0]; # 1
Avantages :
Inconvénients :