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

时间:2013-03-07 17:02:52

标签: perl map

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

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

+在此代码段中执行了哪些操作?我使用Data::Dumper来查看取出加号是否有效,但结果是一样的:

  $ perl cleanme.pl
$VAR1 = {
          'file1' => 1,
          'file2' => 1
        };

2 个答案:

答案 0 :(得分:12)

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

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

@array_of_hashrefs = map {  "\L$_" => 1  }, @array

注意逗号。然后,如果解析器猜测您正在执行此操作,并且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)

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

答案 1 :(得分:7)

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

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


例如,map有两种语法。

map EXPR, LIST

map BLOCK LIST

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

那么map如何区分呢?它猜测。这意味着它有时是错误的。

猜测错误的一个场合是:

map { $_ => 1 }, @list

您可以使用+;进行正确猜测。

map {; ...     # BLOCK
map +{ ...     # EXPR

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

map +{ foo => $_ }, @list

但我更喜欢:

map({ foo => $_ }, @list)

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

print ($x+$y)*2;    # Same as: 2 * print($x+$y)

可以使用

修复
print +($x+$y)*2;

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

print(($x+$y)*2);