develooper Front page | perl.perl5.porters | Postings from October 2014

RE: [perl #123090] Not enough arguments for map

Thread Next
From:
Herington, Dean
Date:
October 31, 2014 14:49
Subject:
RE: [perl #123090] Not enough arguments for map
Message ID:
F39D577FA9891F4195A5EEE008DCA7CD3B59C0FE@MX104CL01.corp.emc.com
Thanks for making me realize that the description of `map` has been enhanced since my edition of the Perl bible was published.

Personally, I would have opted for a much simpler rule:  If what follows `map` is `{`, it starts a BLOCK.  One can always signal an EXPR that's an anonymous hash with `+{`.

I do like the `map +(...), ...` option.

Thanks!

-----Original Message-----
From: Father Chrysostomos via RT [mailto:perlbug-followup@perl.org] 
Sent: Thursday, October 30, 2014 5:52 PM
To: Herington, Dean
Subject: [perl #123090] Not enough arguments for map

On Thu Oct 30 13:55:41 2014, dean.herington@emc.com wrote:
> This is a bug report for perl from dean.herington@emc.com, generated 
> with the help of perlbug 1.39 running under perl 5.16.3.
> 
> 
> -----------------------------------------------------------------
> I don't understand the following error.  I think the result of the 
> following statement should be the same as the similar one shown later.
> 
> DB<1> p map { a => 1 } 1,2,3
> Not enough arguments for map at (eval 9)[C:/Perl/lib/perl5db.pl:646] 
> line 2, near "} 1"
> syntax error at (eval 9)[C:/Perl/lib/perl5db.pl:646] line 2, near "} 
> 1"
> 
> DB<2> $a = 'a'
> 
> DB<3> p map { $a => 1 } 1,2,3
> a1a1a1

The map entry in perlfunc says:

           "{" starts both hash references and blocks, so "map { ..." could be
           either the start of map BLOCK LIST or map EXPR, LIST.  Because Perl
           doesn't look ahead for the closing "}" it has to take a guess at
           which it's dealing with based on what it finds just after the "{".
           Usually it gets it right, but if it doesn't it won't realize
           something is wrong until it gets to the "}" and encounters the
           missing (or unexpected) comma.  The syntax error will be reported
           close to the "}", but you'll need to change something near the "{"
           such as using a unary "+" to give Perl some help:

               %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)

           or to force an anon hash constructor use "+{":

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

           to get a list of anonymous hashes each with only one entry apiece.

So you could say this is not a bug, or a known limitation.  However, I would like to try and fix the most obvious cases, like your examples, so that it just does the right thing.  (That means doing look-ahead to see if there is a comma after the closing brace, which can only work for the most simple code.)

Personally I usually do ‘map +(...), LIST’, since it always works, unless I need multiple statements in the block.

-- 

Father Chrysostomos


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About