In Perl, tutti gli argomenti delle funzioni vengono gestiti attraverso l'array @_. Quando una sottoprogramma viene chiamata, tutti i parametri passati si trovano all'interno di questo array, e inizialmente è una lista, non una copia, cioè se si modifica $_[0], si modifica l'originale.
sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Solo la variabile locale cambia }
sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data ora è (1,2,3,42)
my ($a, $b) = @_ vengono create copie.Se si passa un array a una funzione in Perl così:
myfunc(@arr), e all'interno della funzione si accede a$_[0], cosa ci sarà lì?
Risposta corretta: Ci sarà il primo elemento del valore dell'array, e non un riferimento all'intero array! Per passare un array come oggetto intero, utilizza un riferimento: myfunc(\@arr).
sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Mostrerà 'foo', non un riferimento all'array print_first(\@a); # Mostrerà ARRAY(0x...) — riferimento all'intero array
Storia
update_hash(%global). All'interno si modificava $_[0]. Di conseguenza, veniva modificato solo un segmento locale dell'array di argomenti, e l'hash globale non veniva modificato. La soluzione corretta è stata passare un riferimento: update_hash(\%global).Storia
myfunc(@arr, %opts). Si è scoperto che parte delle chiavi dell'hash veniva sovrascritta dai valori dell'array, e scoprire l'errore era difficile.Storia
Durante l'implementazione di una ricerca ricorsiva in un albero, si voleva modificare gli elementi interni. Gli array venivano passati "così com'erano", non per riferimento. Venivano create copie e le modifiche non influenzavano il contesto esterno. Il problema è stato risolto sostituendo i passaggi con lo stile del riferimento.