In Perl gibt es keine eingebaute Syntax für mehrdimensionale Arrays wie in einigen anderen Sprachen. Stattdessen werden Arrays von Arrays verwendet, bei denen jedes Element der obersten Ebene eine Referenz auf ein anderes Array ist. Diese Organisation ermöglicht es, Tabellen, Matrizen und andere Datenstrukturen, die zwei- oder mehrdimensional sind, flexibel zu modellieren.
Ursprünglich wurde Perl zur Textverarbeitung und zur Arbeit mit einfachen Strukturen entwickelt, doch mit dem Aufkommen von Referenzen (seit Perl 5) erhielten Entwickler die Möglichkeit, komplexe verschachtelte Strukturen zu erstellen – beispielsweise Arrays von Arrays oder Hash-Arrays.
Die größte Diskrepanz im Erwartungen neuer Benutzer: der Versuch, ein zweidimensionales Array einfach zu erstellen – zum Beispiel durch die Deklaration @matrix = ( (1,2), (3,4) ). Dieser Ansatz wird nicht das gewünschte Ergebnis liefern, da die Elemente als skalare Werte entpackt werden und nicht als verschachtelte Strukturen. Ein weiterer häufiger Fehler beim Kopieren von Arrays: flaches Kopieren führt zu unerwarteten Nebeneffekten.
In Perl werden mehrdimensionale Arrays durch Referenzen auf Arrays aufgebaut. Die richtige Initialisierung sieht so aus:
my @matrix; for my $i (0..2) { for my $j (0..2) { $matrix[$i][$j] = $i * $j; } } # Zugriff auf das Element: $matrix[1][2]
Oder durch anonyme Referenzen:
my $matrix = [ [1,2,3], [4,5,6], [7,8,9] ]; print $matrix->[1][2]; # 6
Wichtige Besonderheiten:
Kann man mehrdimensionale Arrays ohne Referenzen nur durch geschachtelte Klammern wie in anderen Sprachen erstellen?
Nein. Perl entpackt in diesem Fall die Elemente wie eine normale Liste. Nur die Verwendung von Referenzen ist korrekt.
Beispiel für fehlerhaften Code:
my @matrix = ((1,2,3),(4,5,6),(7,8,9)); # Elemente in einer Reihe print $matrix[3]; # 4, nicht [4,5,6] – inkorrekte Arbeit
Korrekte Methode:
my @matrix = ( [1,2,3], [4,5,6], [7,8,9] ); print $matrix[1][2]; # 6
Was passiert, wenn man ein Array von Arrays durch einfache Zuweisung kopiert?
Es wird nur die oberste Ebene kopiert, die verschachtelten Arrays verweisen auf dieselben Speicherbereiche.
Beispiel:
my @a = ( [1,2], [3,4] ); my @b = @a; $a[0][0] = 99; print $b[0][0]; # 99, obwohl man 1 erwartet hat – flaches Kopieren!
Kann man ein geschachteltes Array mit eingebauten Mittel von Perl "tief" kopieren?
Nein, Perl bietet keinen Standardoperator für tiefes Kopieren von verschachtelten Strukturen. Man muss das Modul Storable oder eine rekursive Funktion verwenden.
Beispiel mit Storable:
use Storable 'dclone'; my $deepcopy = dclone(\@matrix);
Ein Entwickler erstellt eine zweidimensionale Matrix durch einfaches Array-Deklarieren und kopiert sie durch Zuweisung:
my @m1 = ([1,2],[3,4]);
my @m2 = @m1;
$m1[0][0] = 77;
print $m2[0][0];
Vorteile:
Nachteile:
Verwendung des Storable-Moduls für tiefes Kopieren:
use Storable 'dclone'; my @m1 = ([1,2],[3,4]); my $m2 = dclone(\@m1); $m1[0][0] = 77; print $m2->[0][0]; # 1
Vorteile:
Nachteile: