Storia della questione:
In Perl, le sottoprogrammazioni sono sempre state implementate in modo molto flessibile: qualsiasi chiamata a una sottoprogramma può accettare un numero illimitato di parametri, che vengono messi in un array @_. Questo approccio è adatto per compiti di varia complessità e supporta la dinamicità di Perl.
Problema:
Molti sviluppatori, soprattutto i neofiti, si imbattono nella confusione durante il lavoro con @_ — una distruzione errata dei parametri, la modifica accidentale dei dati in entrata (poiché le variabili vengono passate per valore, e le strutture complesse per riferimento), e la discrepanza tra il numero e i tipi di argomenti. I problemi sorgono quando si restituiscono diversi tipi di dati e si cerca di implementare prototipi di funzioni.
Soluzione:
Per ottenere gli argomenti, la sottoprogramma deve esplicitamente distruggerli dall'array @_. Il ritorno dei valori avviene tramite l'operatore return, il comportamento dipende dal contesto (scalare o di lista). Per evitare effetti collaterali, i parametri vengono spesso presi per copia o per riferimento, se è necessaria una loro modifica all'interno della sottoprogramma. Per le strutture complesse si utilizza la trasmissione per riferimento.
Esempio di codice:
sub add { my ($a, $b) = @_; return $a + $b; } sub change_array { my ($arr_ref) = @_; push @$arr_ref, 100; } my @nums = (1, 2, 3); my $sum = add(5, 10); change_array(\@nums); print join(", ", @nums); # 1, 2, 3, 100
Caratteristiche chiave:
@_La funzione modifica i parametri passati ad essa se si lavora con scalari semplici?
No, gli scalari vengono copiati durante la trasmissione, le loro modifiche non influenzano l'originale. Tuttavia, se l'argomento è un riferimento, i dati originali possono cambiare.
È possibile impostare valori standard per gli argomenti delle sottoprogrammazioni, come in altri linguaggi?
Direttamente no. In Perl è necessario implementare la gestione dei valori predefiniti all'interno del corpo della funzione, utilizzando un controllo defined o il numero di argomenti.
Esempio di codice:
sub foo { my ($arg1, $arg2) = @_; $arg2 //= 10; print "$arg1 $arg2 "; } foo(5); # 5 10
Cosa succede con un accesso diretto a @_ senza copia — per esempio, $a = $_[0]?
Tale assegnazione crea un alias: la modifica di $a cambierà $[0], e viceversa. Si raccomanda di creare copie tramite my ($a) = @; per evitare modifiche inaspettate.
** Caso negativo
Nella funzione per la gestione di un array, è stato dimenticato di copiare i parametri da @_ in variabili locali. Di conseguenza, la modifica della variabile locale ha portato alla modifica dell'array originale, causando bug in altre parti del programma.
Vantaggi:
Svantaggi:
** Caso positivo
Nel team è stata implementata la pratica della distruzione obbligatoria di @_ all'inizio di ogni sottoprogramma, e i grandi oggetti vengono trasferiti solo per riferimento.
Vantaggi:
Svantaggi: