In Perl kann man für das tiefe Kopieren von verschachtelten Strukturen (z. B. Arrays von Hashes, Hashes von Arrays) keine einfache Zuweisung oder Standardschnittstellen verwenden (@b = @a, %b = %a, $clone = $orig). Solche Operationen erzeugen nur eine flache Kopie: die verschachtelten Objekte verweisen weiterhin auf denselben Speicherbereich.
Für das tiefe Kopieren verwendet man:
Storable:use Storable 'dclone'; my $deep_copy = dclone($structure);
Clone: ähnliche Anwendung.Es ist wichtig zu beachten: Alle Ebenen der Verschachtelung, einschließlich der Verweise innerhalb der Struktur, werden kopiert.
Was passiert bei einer einfachen Zuweisung einer komplexen Datenstruktur: Werden die verschachtelten Elemente kopiert?
Antwort: Nein, nur die oberste Ebene wird kopiert. Innere Arrays und Hashes bleiben zwischen dem Original und der Kopie geteilt.
my $orig = { a => [1,2,3], b => { x => 7 } }; my $copy = $orig; $copy->{a}[0] = 99; # $orig->{a}[0] — wird auch 99!
Nur die Verwendung von tiefem Klonen führt zu einer vollständig unabhängigen Kopie.
Geschichte 1
In einer REST-API-Anwendung wurden Anfragen für verschiedene Kunden durch einfache Zuweisung von Verweisen geklont. Infolgedessen spiegelten sich Änderungen an der Antwort eines Kunden sofort bei allen anderen wider — da alle mit der gleichen verschachtelten Datenstruktur arbeiteten.
Geschichte 2
Bei der Aggregation von Daten aus einer komplexen Struktur von Arrays wurde das Kopieren mittels push (push @new, @old) verwendet, wobei die verschachtelten Ebenen vergessen wurden. Eine zufällige Änderung eines inneren Hashes beschädigte die Daten aller Aggregate — der Fehler konnte lange Zeit nicht gefunden werden.
Geschichte 3
Für die Verarbeitung von Protokollen wurde die Struktur im Skript über Clone dupliziert, wobei jedoch besondere "magische" Felder von Objekten nicht berücksichtigt wurden — entsprechend gingen notwendige Methoden/Attribute verloren. Letztendlich war die Funktionalität ungültig, und der Fehler trat nur in der Produktion auf.