Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Perl bug or magic?

by vladb (Vicar)
on Jul 22, 2002 at 14:39 UTC ( [id://184074]=perlquestion: print w/replies, xml ) Need Help??

vladb has asked for the wisdom of the Perl Monks concerning the following question:

Take a look at this code snippets:
my %h = map {"$_" => 1} qw(id title full_text);
and
my %h = map {1; "$_" => 1 } qw(id title full_text);
The first one doesn't compile, alright, giving me this error:
syntax error at bug_or_magic.pl line 6, near "} qw(id title full_text) +"
whereas, simply adding 1; as the first statement of the map() code block (first parameter), appears to have solved the problem. But, my question is "why"? or "how did it solve it"?

Is this a bug with Perl (I'm running Perl version 5.005_03 built for i386-freebsd) or an example of a 'magic' behaviour? ;-)

_____________________
# Under Construction

Replies are listed 'Best First'.
Re: Perl bug or magic?
by Abigail-II (Bishop) on Jul 22, 2002 at 14:45 UTC
    Documented behaviour. From perlfunc, the entry for map:
                   "{" 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 its dealing with based 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 , at end
    
                   and you get list of anonymous hashes each with
                   only 1 entry.
    
    amd from perltrap:
           o Parsing
               When perl sees "map {" (or "grep {"), it has to guess
               whether the "{" starts a BLOCK or a hash reference. If
               it guesses wrong, it will report a syntax error near
               the "}" and the missing (or unexpected) comma.
    
               Use unary "+" before "{" on a hash reference, and
               unary "+" applied to the first thing in a BLOCK (after
               "{"), for perl to guess right all the time. (See "map"
               in perlfunc.)
    

    Abigail

Re: Perl bug or magic?
by gav^ (Curate) on Jul 22, 2002 at 15:53 UTC
    Abigail has the right answer, but I'd like to make the comment that it's just another case where putting un-needed quotes around variables can bite you.

    You should really have written: my %h = map { $_ => 1 } qw(id title full_text);

    gav^

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://184074]
Approved by ehdonhon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2024-04-19 11:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found