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

use strict; 
use warnings; 

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

yo esperaría que el código anterior para imprimir "a, b, c, a, b, c, a, b, c\n", pero en su lugar se muere con el mensaje:¿Por qué aparece un error cuando trato de utilizar el operador de asignación de reptiles con una matriz?

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

Esto parece extraño porque el X <op>= Y están documentados como equivalente a X = X <op> Y, y el siguiente código funciona como Lo espero:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

¿Esto es un error en Perl o estoy malentendiendo lo que debería suceder aquí?

Respuesta

0

El problema es que estás tratando de modificar @a en su lugar, lo que evidentemente Perl no te permite hacer. Su segundo ejemplo es hacer algo sutilmente diferente, que es crear una nueva matriz que consta de @a repetida tres veces, y luego sobrescribir @a con ese valor.

Podría decirse que el primer formulario debe traducirse de forma transparente a la segunda forma, pero eso no es lo que realmente sucede. Podrías considerar esto como un error ... archivarlo en los lugares apropiados y ver qué pasa.

1

Supongo que Perl no es un lenguaje con transformaciones simbólicas completas. Trata de entender lo que quieres decir. Si "list-ify" @a, al ponerlo en parens, pierde de alguna manera lo que quería asignarle.

Tenga en cuenta que esto no hace lo que queremos:

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

Pero, esto hace:

my @b = (@a) x 3; 

Como lo hace:

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

Así que parece que cuando la expresión actally aparece en ambos lados Perl los interpreta en diferentes contextos. Sabe que estamos asignando algo, por lo que trata de descubrir a qué estamos asignando.

Lo atribuiría a un error, a partir de una sintaxis muy raramente utilizada.

+0

Sí, solo lo encontré porque estoy documentando todos los operadores (github.com/cowens/perlopref) y estaba probando mi suposición ingenua de lo que debería hacer. –

+1

No creo que lo llamaría un error, ya que el manual de Perl 4 menciona explícitamente que solo funciona en escalares: http://www.cs.cmu.edu/afs/cs.cmu.edu/Web/People/rgs/pl-exp-op.html # x – mercator

+0

@mercator Ese no es el manual de Perl (que podría ser el Camel o algo accesible desde 'perldoc'). El hecho de que documente el mismo comportamiento no significa que el comportamiento no sea un error. Ver http://perldoc.perl.org/perlop.html#Assignment-Operators para la documentación actual (5.10.1). –

4

Mi primer pensamiento fue que era un malentendido de alguna sutileza por parte de Perl, es decir, que los parens alrededor de @a lo analizaban como un intento de asignar a una lista. (. La lista en sí, no es normal asignación de lista) Esta conclusión parece estar apoyada por 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.

Al parecer, ese no es el caso, sin embargo. Si se tratara de esto debe tener el mismo error:

($x) x= 3; # ok 

Más concluyente, esto da el mismo error:

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

Ergo, sin duda un error. Archivo.

Cuestiones relacionadas