9

在此代码段中:

    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

4 回答 4

8

那是%(变量的哈希切片,它是*(全局的一部分,不受严格变量的约束。这对于 Perl 已经预定义的变量是正确的,在这种情况下$(,对于所有其他用于标点符号变量名称的 glob 槽也是如此。所有标点符号变量在所有包中都是全局的,它们的完全限定名称是缩写形式:$), @), %), &)... 由于strict 'vars'不适用于完全限定名称,因此这些名称都不是错误的。

扩展一点:

@({$r};
@{(}{$r};
@{'main::('}{$r};  # needs strict refs to be off

这些行都是等价的。

使用use warnings;perl 会让您知道最好用$sigil 编写单个值的切片:

$({$r};
${(}{$r};
${'main::('}{$r};  # needs strict refs to be off

在尝试解决错字时,会为您指出正确的位置。这就是为什么您应该始终同时使用警告和限制的原因。

有关更多详细信息,perlvar联机帮助页显示了所有带有至少一个印记或其他印记的标点符号变量。如果您想要有关标点符号变量范围的参考,请参阅文档。


所有标点符号变量也不受used only once警告影响,这可能是一个错误......

于 2011-11-22T01:32:53.483 回答
3

@({$r}是散列的散列片(记录在perldata中)%(

%h = (a=>1, b=>2, c=>3);
say for @h{qw( a c )};  # 1 3

Perl 本身不使用%(,所以它肯定是空的。

你肯定打算使用@{$r},一个相当复杂的方式或写作@$r

于 2011-11-22T01:34:23.747 回答
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仍然存在)。

请注意,这$(是一个有效的预定义变量(它是当前进程的真实组 ID),所以看起来像不匹配括号的东西不一定是错误。

看起来这只是一个拼写错误,由于不明原因,Perl 没有抱怨。

改为@({$r}@{$r}你(大概)真正想做的事情。

于 2011-11-22T01:36:55.057 回答
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:: 树,它真的很有帮助

于 2011-11-22T09:32:15.653 回答