11

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

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

此代码段中的作用是什么+?我曾经Data::Dumper看看取出加号是否有任何作用,但结果是一样的:

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

2 回答 2

13

这用于防止解析问题。加号强制解释器表现得像一个普通的块,而不是一个表达式。

担心的是,也许您正试图使用​​类似的其他(表达式)公式来创建哈希引用map

@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

于 2013-03-07T17:08:25.073 回答
8

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

在您给出的示例中,它完全没用。但是在某些情况下,将下一个令牌制作成无可否认的运算符是有用的。


例如,map有两种语法。

map EXPR, LIST

map BLOCK LIST

块以 开头{,但表达式也可以。例如,{ }可以是块或哈希构造函数。

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

猜测错误的一种情况如下:

map { $_ => 1 }, @list

+您可以使用or来促使它正确猜测;

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

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

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

请注意,您还可以使用以下内容:

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

另一个示例是当您省略参数周围的括号时,第一个参数表达式以括号开头。

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

它可以使用固定

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

但是,为什么要为了避免括号而增加黑客攻击呢?我更喜欢

print(($x+$y)*2);
于 2013-03-07T17:25:06.143 回答