为什么这个地图块包含一个明显无用的+?

Alb*_*lby 11 perl map

浏览源代码时,我看到以下几行:

my @files_to_keep = qw (file1 file2);
my %keep = map { + $_ => 1 } @files_to_keep;
Run Code Online (Sandbox Code Playgroud)

+这段代码片段做了什么?我曾经Data::Dumper看过取出加号是否做了什么,但结果是一样的:

  $ perl cleanme.pl
$VAR1 = {
          'file1' => 1,
          'file2' => 1
        };
Run Code Online (Sandbox Code Playgroud)

Joe*_*ger 12

这用于防止解析问题.加号表示强制解释器的行为类似于普通块而不是表达式.

令人担心的是,您可能正在尝试使用其他(表达式)公式来创建一个hash参考map.

@array_of_hashrefs = map {  "\L$_" => 1  }, @array
Run Code Online (Sandbox Code Playgroud)

注意逗号.然后,如果解析器猜测您正在执行此操作,并且OP中的语句将缺少逗号的语法错误!要看到区别,请尝试引用"$_".无论出于何种原因,解析器都会将其视为足以触发表达式行为.

是的,这很奇怪.因此,许多超偏执的Perl程序员经常在需要的时候投入额外的加号(包括我).

以下是map文档中的示例.

%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 {  lc($_) => 1  } @array  # as does this.
%hash = map +( lc($_) => 1 ), @array  # this is EXPR and works!
%hash = map  ( lc($_), 1 ),   @array  # evaluates to (1, @array)
Run Code Online (Sandbox Code Playgroud)

有趣的阅​​读(风格)和解析器错误的情况请阅读:http://blogs.perl.org/users/tom_wyant/2012/01/the-case-of-the-overloaded-curlys.html


ike*_*ami 7

一元加运算符只是返回其操作数不变.添加一个甚至不会改变上下文.

在你给出的例子中,它完全没用.但有些情况下,使下一个令牌无疑是一个操作员是有用的.


例如,map有两种语法.

map EXPR, LIST
Run Code Online (Sandbox Code Playgroud)

map BLOCK LIST
Run Code Online (Sandbox Code Playgroud)

一个块以{,但表达式也可以.例如,{ }可以是块或散列构造函数.

那怎么能map分辨出来呢?它猜测.这意味着它有时是错误的.

猜测错误的一个场合是:

map { $_ => 1 }, @list
Run Code Online (Sandbox Code Playgroud)

你可以刺激它使用+或正确猜测;.

map {; ...     # BLOCK
map +{ ...     # EXPR
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,你可以使用

map +{ foo => $_ }, @list
Run Code Online (Sandbox Code Playgroud)

但是我更喜欢:

map({ foo => $_ }, @list)
Run Code Online (Sandbox Code Playgroud)

另一个例子是当你省略参数周围的parens时,第一个参数表达式以paren开头.

print ($x+$y)*2;    # Same as: 2 * print($x+$y)
Run Code Online (Sandbox Code Playgroud)

它可以使用固定

print +($x+$y)*2;
Run Code Online (Sandbox Code Playgroud)

但为什么要堆放在黑客上只是为了避免parens?我更喜欢

print(($x+$y)*2);
Run Code Online (Sandbox Code Playgroud)