2014-06-07 23 views
5

Conosco la subroutine in perl pass arg per riferimento. Ma nel codice sottostante, il ciclo foreach nella subroutine non dovrebbe modificare il valore per @list perché lo my $i dovrebbe creare una nuova variabile in modo lessicale var $i. Qualsiasi assegnazione a $i dovrebbe essere in ambito lessicale ma non modificare il valore @list.perl ciclo foreach nella subroutine

Qualcuno può spiegare cosa sta succedendo all'interno del ciclo di foreach che causa il cambio di valore a @list?

sub absList {  
    foreach my $i (@_) { 
     $i = abs($i); 
    } 
} 

@list = (-2,2,4,-4); 
absList(@list); 
print "@list"; 

Uscite:

2 2 4 4 

risposta

5

$i è alias agli elementi di matrice @_ dovuta foreach caratteristica (e @_ elementi sono alias per gli elementi del @list dovuta @_magic).

Da perldoc

Se qualsiasi elemento di LISTA è un lvalue, è possibile modificarlo modificando VAR all'interno del ciclo. Viceversa, se qualche elemento di LIST NON è un lvalue, qualsiasi tentativo di modificare quell'elemento fallirà. In altre parole, la variabile di indice del ciclo foreach è un alias implicito per ogni elemento dell'elenco su cui si sta eseguendo il ciclo.

Se si desidera evitare tale comportamento, non iterare direttamente sopra l'array @_, ad es.

sub absList { 
    my @arr = @_; 
    foreach my $i (@arr) { 
     $i = abs($i); 
    } 
} 
+0

Grazie per i collegamenti alle informazioni. Significa che '$ i' in foreach sarà sempre referenziato/con alias al @arr indipendentemente dal fatto che lo sto usando con/senza' my'. E se '@ arr' è la variabile speciale' @ _', significa che '$ i' sarà il valore reale degli elementi in' @ _'. Assegnare qualsiasi valore a '$ i' significa cambiare il valore degli elementi in' $ @ '. Ho ragione? – user2763829

+1

@ user2763829 sì, 'mio' definisce solo l'ambito per la variabile di iterazione. –

+0

Grazie. Anche senza 'my' in' foreach', '$ i' passerà sempre all'interno del ciclo' foreach' dato che '$ i' sarà scope localmente. Quindi c'è davvero bisogno di dichiarare il 'mio' per' $ i' (in questo scenario o in qualsiasi altro scenario)? – user2763829

2

$i qui si riferisce elementi della lista che ottiene dalla @_, ecco perché cambiando $i cause cambiano nel rispettivo elemento dell'elenco.