2009-09-08 9 views
7
#!/usr/bin/perl 

use strict; 
use warnings; 

my @a = qw/a b c/; 
(@a) x= 3; 
print join(", ", @a), "\n"; 

mi aspetterei che il codice di cui sopra per stampare "a, b, c, a, b, c, a, b, c\n", ma invece muore con il messaggio:Perché viene visualizzato un errore quando provo a utilizzare l'operatore di assegnazione di rettifica con un array?

Can't modify private array in repeat (x) at z.pl line 7, near "3;" 

Questo sembra strano perché il X <op>= Y sono documentate come equivalente a X = X <op> Y, e il seguente codice funziona come mi aspetto che:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @a = qw/a b c/; 
(@a) = (@a) x 3; 
print join(", ", @a), "\n"; 

si tratta di un bug in Perl o sto equivoco che cosa dovrebbe accadere qui?

risposta

0

Il problema è che si sta tentando di modificare @a sul posto, che Perl evidentemente non consente di fare. Il tuo secondo esempio sta facendo qualcosa di leggermente diverso, che è quello di creare un nuovo array costituito da @a ripetuto tre volte, quindi sovrascrivendo @a con quel valore.

Probabilmente il primo modulo deve essere tradotto in modo trasparente nel secondo modulo, ma non è ciò che accade realmente. Potresti considerare questo un bug ... archiviarlo nei posti appropriati e vedere cosa succede.

1

La mia ipotesi è che il Perl non sia un linguaggio con trasformazioni simboliche complete. Cerca di capire cosa intendi. Se "list-ify" @a, mettendolo in parens, perde qualcosa a cui si desidera assegnarlo.

Si noti che questo non fa quello che vogliamo:

my @b = @a x 3; # we'll get scalar(@a) --> '3' x 3 --> '333' 

Ma, questo fa:

my @b = (@a) x 3; 

Come fa:

(@a) = (@a) x 3; 

Così sembra che quando l'espressione appare in modo formale su entrambi i lati Perl li interpreta in diversi contesti. Sa che stiamo assegnando qualcosa, quindi cerca di scoprire a cosa stiamo assegnando.

Scrivo su un errore, da una sintassi utilizzata raramente.

+0

Sì, ci ho provato solo perché sto documentando tutti gli operatori (github.com/cowens/perlopref) e stavo testando la mia assunzione ingenua di cosa avrebbe dovuto fare. –

+1

Non penso che lo definirei un bug, dal momento che il manuale di Perl 4 menziona esplicitamente che funziona solo su scalari: http://www.cs.cmu.edu/afs/cs.cmu.edu/Web/Persone/rgs/pl-exp-op.html # x – mercator

+0

@mercator Questo non è il manuale di Perl (che sarebbe o il Cammello o qualcosa accessibile da 'perldoc'). Il fatto che documenti lo stesso comportamento non significa che il comportamento non sia un bug. Vedi http://perldoc.perl.org/perlop.html#Assignment-Operators per la documentazione corrente (5.10.1). –

4

Il mio primo pensiero fu che si trattava di un fraintendimento di una certa sottigliezza da parte di Perl, e cioè che il paren intorno allo @a lo fece analizzare come un tentativo di assegnarlo a una lista. (. La lista in sé, non è normale assegnazione lista) Tale conclusione sembra essere supportata da perldiag:

Can't modify %s in %s

(F) You aren't allowed to assign to the item indicated, or otherwise try to change it, such as with an auto-increment.

A quanto pare non è questo il caso, però. Se fosse questo dovrebbe avere lo stesso errore:

($x) x= 3; # ok 

Più conclusivamente, questo dà lo stesso errore:

@a x= 3; # Can't modify private array in repeat... 

Ergo, sicuramente un bug. File.

Problemi correlati