#!/usr/bin/perl
use strict;
use warnings;
my @a = qw/a b c/;
(@a) x= 3;
print join(", ", @a), "\n";
我希望上面的代码可以打印"a, b, c, a, b, c, a, b, c\n"
,但它会消失:
Can't modify private array in repeat (x) at z.pl line 7, near "3;"
这看起来很奇怪,因为X <op>= Y
被记录为等同于X = X <op> Y
,并且以下代码按预期工作:
#!/usr/bin/perl
use strict;
use warnings;
my @a = qw/a b c/;
(@a) = (@a) x 3;
print join(", ", @a), "\n";
这是Perl中的错误还是我误解了应该发生什么?
答案 0 :(得分:4)
我的第一个想法是,这是对Perl的一些微妙的误解,即@a
周围的parens将其解析为尝试分配到列表。 (列表本身,而不是正常的列表分配。)这个结论似乎得到了perldiag的支持:
无法修改%s中的%s
(F)您不得分配给指定的项目,或以其他方式尝试 改变它,例如自动增量。
显然情况并非如此。如果是这应该有相同的错误:
($x) x= 3; # ok
更确切地说,这给出了同样的错误:
@a x= 3; # Can't modify private array in repeat...
Ergo,绝对是个错误。归档。
答案 1 :(得分:1)
我的猜测是Perl不是一种具有完全符号转换的语言。它试图找出你的意思。如果你“list-ify”@a
,把它放在parens中,就会丢失你想要分配给它的东西。
请注意,这不符合我们的要求:
my @b = @a x 3; # we'll get scalar( @a ) --> '3' x 3 --> '333'
但是,这样做:
my @b = ( @a ) x 3;
同样如此:
( @a ) = ( @a ) x 3;
所以看来,当表达式在双方都出现时,Perl会在不同的语境中解释它们。它知道我们正在分配一些东西,所以它试图找出我们要分配的内容。
我会用很少使用的语法将它归结为一个错误。
答案 2 :(得分:0)
问题是你正在尝试修改@a,Perl显然不允许你这样做。你的第二个例子是做一些微妙的不同,即创建一个由@a重复三次组成的新数组,然后用该值覆盖@a。
可以说第一种形式应该透明地翻译成第二种形式,但事实并非如此。您可以将此视为一个错误...将其存放在适当的位置,看看会发生什么。