In Perl erfolgt die Argumentation von Funktionen über das Array @_. Bei einem Aufruf des Unterprogramms befinden sich alle übergebenen Parameter in diesem Array, und ursprünglich handelt es sich um eine Liste und nicht um eine Kopie, das heißt, wenn Sie $_[0] ändern, ändern Sie das Original.
sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Nur die lokale Variable ändert sich }
sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data ist jetzt (1,2,3,42)
my ($a, $b) = @_ werden Kopien erstellt.Wenn Sie in Perl eine Funktion ein Array so übergeben:
myfunc(@arr)und innerhalb der Funktion auf$_[0]zugreifen, was wird dort sein?
Richtige Antwort: Dort wird das erste Element des Wertes des Arrays sein, nicht die Referenz auf das gesamte Array! Um ein Array als Ganzes zu übergeben, verwenden Sie die Referenz: myfunc(\@arr).
sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Gibt 'foo' aus, nicht die Referenz auf das Array print_first(\@a); # Gibt ARRAY(0x...) aus — Referenz auf das gesamte Array
Geschichte
update_hash(%global). Innen wurde $_[0] verändert. Infolgedessen wurde nur ein lokaler Ausschnitt des Argumentarrays geändert, und der globale Hash wurde nicht modifiziert. Die korrekte Lösung war die Übergabe einer Referenz: update_hash(\%global).Geschichte
myfunc(@arr, %opts). Es stellte sich heraus, dass einige Schlüssel des Hashes durch die Werte des Arrays überschrieben wurden, und es war nicht einfach, den Fehler zu finden.Geschichte
Bei der Implementierung der rekursiven Traversierung eines Baumes wollte man interne Elemente ändern. Die Arrays wurden "so wie sie sind" an die Funktion übergeben, nicht per Referenz. Sie erzeugten Kopien, und die Änderungen hatten keinen Einfluss auf den externen Kontext. Das Problem wurde durch den Wechsel zu dem Referenzstil behoben.