Perl 使用映射函数时出现语法错误

Perl 使用映射函数时出现语法错误,perl,dictionary,syntax-error,map-function,Perl,Dictionary,Syntax Error,Map Function,我在使用map函数的Perl程序中遇到了一个奇怪的语法错误。我有一个简单的解决方法(添加看似不必要的括号),所以这并不重要,但我不知道为什么Perl会在原始代码中报告语法错误,或者为什么添加括号会修复它 我想创建一个散列,将一系列短字符串(每个字符串以“-”开头)映射到值1(基本上是一个集合数据结构)。我的第一次尝试与此类似: my %hash = map { "-$_" => 1 } qw(foo bar); 我认为这相当于: my %hash = ( "-foo" => 1,

我在使用
map
函数的Perl程序中遇到了一个奇怪的语法错误。我有一个简单的解决方法(添加看似不必要的括号),所以这并不重要,但我不知道为什么Perl会在原始代码中报告语法错误,或者为什么添加括号会修复它

我想创建一个散列,将一系列短字符串(每个字符串以“-”开头)映射到值
1
(基本上是一个集合数据结构)。我的第一次尝试与此类似:

my %hash = map { "-$_"  => 1 } qw(foo bar);
我认为这相当于:

my %hash = ( "-foo" => 1, "-bar" => 1 );
Perl报告了一个语法错误。如果我用任何单引号或双引号字符串文字替换
“-$\u”
,我会得到一个语法错误。如果我用
(“-$”
)替换
“-$”
,语法错误就会消失,代码工作正常

我在Perl5.10.1、5.16.2和5.20.0中得到了类似的结果

下面是一个显示问题的自包含脚本(我删除了
-
前缀,因为它似乎不相关):

以及尝试使用Perl 5.20.0运行时的输出:

映射错误第8行“}qw(foo-bar)”附近的语法错误 映射错误第9行“}qw(foo-bar)”附近的语法错误 映射错误第10行“}qw(foo-bar)”附近的语法错误 由于编译错误,映射错误的执行被中止。 (对于Perl 5.10.1和5.16.2,它还抱怨第8行的“没有足够的map参数”)

我已经确认,当注释掉另外两行时,这三个语法错误中的每一个仍然单独出现,因此第9行和第10行不是第8行的级联错误

这是Perl中的一个bug,还是我遗漏了Perl语法的一些细微之处,或者其他什么

{
同时启动散列引用和块,因此
map{…
可以是map BLOCK LIST或map EXPR,LIST的开始。因为Perl不提前查找结束的
}
它必须根据在
之后找到的内容猜测它正在处理的是哪一个{
。通常它是正确的,但如果它不正确,它就不会意识到有什么问题,直到它到达
}
并遇到缺少的(或意外的)逗号。语法错误将在
}
附近报告,但您需要更改
附近的内容{
例如使用一元
+
或分号为Perl提供一些帮助:

    %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 { ("\L$_" => 1) } @array # as does this
    %hash = map {  lc($_) => 1  } @array # and this.
    %hash = map +( lc($_) => 1 ), @array # this is EXPR and works!

    %hash = map  ( lc($_), 1 ),   @array # evaluates to (1, @array)
或使用
+{
强制anon哈希构造函数:

    @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
                                           # comma at end
获取匿名哈希的列表,每个哈希只有一个条目

还骗
    @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
                                           # comma at end