In Perl gebeurt alle argumentatie van functies via de array @_. Bij het aanroepen van een subprogramma komen alle doorgegeven parameters binnen in deze array, en in eerste instantie is dit een lijst, en geen kopie, dus als je $_[0] verandert, wijzig je het origineel.
sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Alleen de lokale variabele verandert }
sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data is nu (1,2,3,42)
my ($a, $b) = @_ worden er kopieën gemaakt.Als je in Perl een functie het array zo doorgeeft:
myfunc(@arr), en binnen de functie aanspreekt tot$_[0], wat zit daar dan in?
Juist antwoord: Daar zit het eerste element van de waarde van de array, en niet de referentie naar de hele array! Om een array als een geheel object door te geven, gebruik je een referentie: myfunc(\@arr).
sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Geeft 'foo' weer, en geen referentie naar de array print_first(\@a); # Geeft ARRAY(0x...) weer — verwijzing naar de hele array
Geschiedenis
update_hash(%global). Binnen werd $_[0] gewijzigd. Het resultaat — alleen een lokaal deel van de array van argumenten werd gewijzigd, terwijl de globale hash niet werd aangepast. De correcte oplossing was het doorgeven van een referentie: update_hash(\%global).Geschiedenis
myfunc(@arr, %opts). Het bleek dat een deel van de hash-sleutels werd vervangen door de waarden van de array, en het was moeilijk om de fout te ontdekken.Geschiedenis
Bij de implementatie van recursieve doorloop van een boom wilden ze interne elementen wijzigen. Arrays werden "zoals ze zijn" doorgegeven, niet per referentie. Ze maakten kopieën, en wijzigingen hadden geen invloed op de externe context. Het probleem werd opgelost door de overdrachten te vervangen door de referentiestijl.