`sub bar {+ {$ _ [1] => $ _ [2]}}`究竟呢?

时间:2015-07-03 07:48:29

标签: perl hash

我不明白这个例子中的+糖标志是在护目镜的某个地方拍摄的:

sub bar { +{$_[1] => $_[2]} }

我写了这篇文章,我认为这里没有任何差异:

use Data::Dumper;

# Not any differences here
my $foo =  {value => 55};
my $bar = +{value => 55};

print Dumper $foo;
print Dumper $bar;

# Oh ! Here there is something...
sub foo {  {$_[1] => $_[2]} };
sub bar { +{$_[1] => $_[2]} };

print Dumper foo('value', 55);    
print Dumper bar('value', 55);    

foo返回

$VAR1 = 55;
$VAR2 = undef;

bar返回

$VAR1 = {
          '55' => undef
        };

1 个答案:

答案 0 :(得分:16)

它有助于解析器区分匿名哈希和代码块。

引用Learning Perl Objects, References & Modules

  

因为块和匿名哈希构造函数都在语法树中大致相同的位置使用花括号,所以编译器必须对这两者中的哪一个进行临时确定。如果编译器决定不正确,您可能需要提供提示以获得所需内容。要向编译器显示您想要匿名哈希构造函数,请在左大括号前加上一个加号:+ {...}。为了确保获得一个代码块,只需在块的开头放一个分号(表示一个空语句):{; ......}。

或者来自map函数的文档:

"{" starts both hash references and blocks, so "map { ..." could
be either the start of map BLOCK LIST or map EXPR, LIST. Because
Perl doesn't look ahead for the closing "}" it has to take a guess
at which it's dealing with based on what it finds just after the
"{". Usually it gets it right, but if it doesn't it won't realize
something is wrong until it gets to the "}" and encounters the
missing (or unexpected) comma. The syntax error will be reported
close to the "}", but you'll need to change something near the "{"
such as using a unary "+" or semicolon to give Perl some help:

    %hash = map {  "\L$_" => 1  } @array # perl guesses EXPR. wrong
    %hash = map { +"\L$_" => 1  } @array # perl guesses BLOCK. right
    %hash = map {; "\L$_" => 1  } @array # this also works
    %hash = map { ("\L$_" => 1) } @array # as does this
    %hash = map {  lc($_) => 1  } @array # and this.
    %hash = map +( lc($_) => 1 ), @array # this is EXPR and works!

    %hash = map  ( lc($_), 1 ),   @array # evaluates to (1, @array)

or to force an anon hash constructor use "+{":

    @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
                                           # comma at end

to get a list of anonymous hashes each with only one entry apiece.