在浏览源代码时,我看到了以下几行:
my @files_to_keep = qw (file1 file2);
my %keep = map { + $_ => 1 } @files_to_keep;
此代码段中的作用是什么+
?我曾经Data::Dumper
看看取出加号是否有任何作用,但结果是一样的:
$ perl cleanme.pl
$VAR1 = {
'file1' => 1,
'file2' => 1
};
这用于防止解析问题。加号强制解释器表现得像一个普通的块,而不是一个表达式。
担心的是,也许您正试图使用类似的其他(表达式)公式来创建哈希引用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
一元加运算符只是简单地返回其操作数不变。添加一个甚至不会改变上下文。
在您给出的示例中,它完全没用。但是在某些情况下,将下一个令牌制作成无可否认的运算符是有用的。
例如,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);