在浏览源代码时,我看到以下几行:
my @files_to_keep = qw (file1 file2);
my %keep = map { + $_ => 1 } @files_to_keep;
+
在此代码段中执行了哪些操作?我使用Data::Dumper
来查看取出加号是否有效,但结果是一样的:
$ perl cleanme.pl
$VAR1 = {
'file1' => 1,
'file2' => 1
};
答案 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);