Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 pondering the Monastery: (4)
As of 2024-04-23 22:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found