在此代码段中:
use strict;
use warnings;
use Data::Dumper;
my $r = [qw(testing this thing)];
print Dumper($r);
foreach my $row (@({$r})
{
print "$row\n";
$row .= 'mod';
}
print Dumper($r);
print Dumper(@({$r});
我发现foreach中'(
'之后的'@
'导致它无法正确循环。我不知道为什么这个代码甚至可以工作,因为没有结束括号。这是做什么的?它看起来是在动态创建一个新变量,但不应该'use strict
'已经解雇了什么?
请帮助解释'@(
'正在做什么以及为什么它仍然在没有结束括号的情况下运行。
答案 0 :(得分:8)
这是%(
变量的哈希切片,它是*(
glob的一部分,不受严格的变量的限制。对于Perl已预定义的变量(在本例中为$(
)以及标点变量名称的所有其他glob时隙也是如此。所有标点符号变量在所有包中都是全局的,其完全限定名称是简短形式:$)
,@)
,%)
,&)
...从{{1}开始}不适用于完全限定名称,这些名称都不是错误。
扩大一点:
strict 'vars'
这些线都是等价的。
使用@({$r};
@{(}{$r};
@{'main::('}{$r}; # needs strict refs to be off
perl会告诉您最好使用use warnings;
sigil写一个单个值的切片:
$
在尝试解决拼写错误时会指出你在正确的位置。这就是为什么你应该总是同时使用警告和限制。
有关更多详细信息,perlvar联机帮助页显示了至少有一个或多个符号的所有标点符号变量。如果你想要一个关于标点符号变量范围的参考,那么package文档就有了。
所有标点符号变量也不受$({$r};
${(}{$r};
${'main::('}{$r}; # needs strict refs to be off
警告的影响,这可能是一个错误......
答案 1 :(得分:3)
@({$r}
是哈希%(
中的哈希切片(记录在perldata中)。
%h = (a=>1, b=>2, c=>3);
say for @h{qw( a c )}; # 1 3
Perl本身不使用%(
,所以肯定是空的。
您肯定打算使用@{$r}
,这是一种相当复杂的方式或写@$r
。
答案 2 :(得分:2)
当我在其上运行perl -cw
时,它会说:
Scalar value @({$r} better written as $({$r} at tmp.pl line 7.
Scalar value @({$r} better written as $({$r} at tmp.pl line 13.
$r
是对数组的引用。正如Eric Strom刚刚发布的那样,@({$r}
是%(
哈希变量的哈希切片。
您从未声明%(
,并且它不是perldoc perlvar
中列出的预定义变量之一。那么为什么不use strict; use warnings;
导致Perl抱怨呢?它可能只是假定任何名称为标点符号的变量是预定义的(比跟踪哪些变量更简单,其中一些可能是undef
)。
请注意$(
是一个有效的预定义变量(它是当前进程的真实group-id),所以看起来像一个不匹配的括号不是必然错误。
看起来这只是一个错字,由于不明原因,Perl没有抱怨。
将@({$r}
更改为@{$r}
以执行您(可能)实际上要执行的操作。
答案 3 :(得分:0)
它没有为我点击,这是一个哈希切片,直到我通过B :: Concise运行它
$ perl -MO=Concise junk
Scalar value @({$r} better written as $({$r} at junk line 7.
Scalar value @({$r} better written as $({$r} at junk line 13.
junk syntax OK
1l <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
...
...
1h <@> hslice lKM ->1i
1d <0> pushmark s ->1e
1e <0> padsv[$r:335,339] l ->1f
1g <1> rv2hv[t17] sKR/3 ->1h
1f <#> gv[*(] s ->1g
- <1> ex-rv2cv sK/2 ->-
1i <#> gv[*Dumper] s ->1j
hslice意味着哈希切片:)了解你的B ::树,它真的很有帮助