什么是'@('在这个Perl代码中做什么?

时间:2011-11-22 01:05:03

标签: perl variable-declaration

在此代码段中:

    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'已经解雇了什么?

请帮助解释'@('正在做什么以及为什么它仍然在没有结束括号的情况下运行。

4 个答案:

答案 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 ::树,它真的很有帮助