使用map函数的语法错误

时间:2015-07-29 23:13:37

标签: perl dictionary syntax-error map-function

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

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

1

我认为应该相当于:

my %hash = map { "-$_"  => 1 } qw(foo bar);

Perl报告了语法错误。如果我用任何单引号或双引号字符串文字替换my %hash = ( "-foo" => 1, "-bar" => 1 ); ,我会收到语法错误。如果我将"-$_"替换为"-$_",语法错误就会消失,代码也能正常运行。

我在Perl 5.10.1,5.16.2和5.20.0中获得了类似的结果。

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

-

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

#!/usr/bin/perl

use strict;
use warnings;

my %h0 = map {   $_   => 1 } qw(foo bar);  # ok
my %h1 = map { ("$_") => 1 } qw(foo bar);  # ok
my %h2 = map {  "$_"  => 1 } qw(foo bar);  # line 8, syntax error
my %h3 = map { 'FOO'  => 1 } qw(foo bar);  # line 9, syntax error
my %h4 = map { "FOO"  => 1 } qw(foo bar);  # line 10, syntax error

(使用Perl 5.10.1和5.16.2,它也会抱怨"地图上没有足够的参数"第8行。)

我已经确认,当其他两行被注释掉时,三个语法错误中的每一个仍然是孤立的,因此第9行和第10行不是来自第8行的级联错误。

这是Perl中的一个错误,还是我错过了Perl语法的一些细微之处,或其他什么?

1 个答案:

答案 0 :(得分:4)

perldoc -f map

  

{启动散列引用和块,因此map { ...可以是映射BLOCK LIST的开头或映射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
     

获取一个匿名哈希列表,每个哈希只有一个条目。