In Perl, gli argomenti di subroutine memorizzati in @_
sono sempre alias dei valori nel sito di chiamata. Questo aliasing persiste solo in @_
, se si copiano valori, questo è ciò che si ottiene, valori.
quindi in questo sottogruppo:
sub example {
# @_ is an alias to the arguments
my ($x, $y, @rest) = @_; # $x $y and @rest contain copies of the values
my $args = \@_; # $args contains a reference to @_ which maintains aliases
}
noti che questa aliasing avviene dopo espansione lista, quindi se passato un array di example
, la matrice si espande nel contesto lista, e @_
è impostato alias di ciascun elemento dell'array (ma l'array stesso non è disponibile per example
). Se si voleva il secondo, si passerebbe un riferimento alla matrice.
L'alias degli argomenti di subroutine è una funzionalità molto utile, ma deve essere utilizzata con attenzione. Per impedire modifiche involontarie di variabili esterne, in Perl 6 è necessario specificare che si desidera argomenti con alias scrivibili con is rw
.
Uno dei trucchi meno conosciuti ma utile è quello di utilizzare questa funzione aliasing per creare arbitri matrice di alias
my ($x, $y) = (1, 2);
my $alias = sub {\@_}->($x, $y);
$$alias[1]++; # $y is now 3
o fette di alias:
my $slice = sub {\@_}->(@somearray[3 .. 10]);
risulta anche che l'uso sub {\@_}->(LIST)
a creare un array da un elenco è in realtà più veloce di
[ LIST ]
poiché Perl non ha bisogno di copiare ogni valore. Ovviamente lo svantaggio (o il rialzo a seconda della prospettiva) è che i valori rimangono alias, quindi non è possibile cambiarli senza cambiare gli originali.
Come tchrist menziona in un commento ad un'altra risposta, quando si utilizza uno dei costrutti di aliasing del Perl sul @_
, il $_
che essi forniscono voi è anche un alias per gli argomenti originali subroutine. Come ad esempio:
sub trim {s!^\s+!!, s!\s+$!! for @_} # in place trimming of white space
Infine tutto questo comportamento è affiancabile, così quando si utilizza @_
(o una fetta di esso) nella lista degli argomenti di un'altra subroutine, si arriva anche alias per gli argomenti della prima subroutine:
sub add_1 {$_[0] += 1}
sub add_2 {
add_1(@_) for 1 .. 2;
}
Perl non è C. Non aspettatevi che si comporti come C, o qualsiasi linguaggio derivato da C come C++ o Java. –
[perldoc perlsub] (http://perldoc.perl.org/perlsub.html) – Ether
La tua domanda riguarda '@ _', non' $ _'. E '@ _' in un' sub' spesso contiene alias piuttosto che copie di valori. Quindi se non vuoi questo comportamento nel tuo 'sub', assicurati di copiare l'input da' @ _' alle variabili 'my' all'inizio. – aschepler