Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: map problem

by GrandFather (Saint)
on Mar 09, 2012 at 11:13 UTC ( [id://958682]=note: print w/replies, xml ) Need Help??


in reply to map problem

Not a bug (really) and not stupid, just a subtle foible of Perl that bites occasionally. From the perlfunc documentation 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:
  1. %hash = map { "\L$_", 1 } @array # perl guesses EXPR. wrong
  2. %hash = map { +"\L$_", 1 } @array # perl guesses BLOCK. right
  3. %hash = map { ("\L$_", 1) } @array # this also works
  4. %hash = map { lc($_), 1 } @array # as does this.
  5. %hash = map +( lc($_), 1 ), @array # this is EXPR and works!
True laziness is hard work

Replies are listed 'Best First'.
Re^2: map problem
by Marshall (Canon) on Mar 09, 2012 at 13:43 UTC
    I also found that adding a string cat operation seemed to clarify things enough for the parser also. I'm not sure which of the various solutions is "the best" if there even is such a thing!
    #!/usr/bin/perl -w use strict; use Data::Dumper; my %x = map {; "prefix_$_" => 1 } qw(a b c); my %y = map { "prefix_"."$_" => 1 } qw(a b c); my %z = map { ''."prefix_$_" => 1 } qw(a b c); print Dumper \%y, \%x, \%z;

      I like a modification of your middle suggestion best:

      my %y = map { "prefix_".$_ => 1 } qw(a b c);
      There's no need to put $_ inside quotes, only to have Perl do variable interpolation on that string. :)

      Alex / talexb / Toronto

      "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

        That will work just fine and dandy as near as I can tell.
        GREAT! - understandable! (in terms of what it does).
        For something like this I would probably add a comment in the code for others as tip to why this "understandable thing" was needed. Not just for the future readers, but you may even forget "why" after a few years. That stuff has happened to me before! If the technique is so tricky that you had to think a lot about it, put in a comment.

        But, yes,  "prefix_".$_ => 1 is "easy on the eyes" (and the brain)

      I like the variant with the semicolon best, because it's the most explicit way to say that something should be parsed as a block. Which conveys a clear message to the maintenance programmer: I wanted a block here, and you'd better leave the semicolon there.

      Relying on the exact semantics of the disambiguation heuristics doesn't leave any traces in the code that there was a problem, and the unsuspecting maintenance programmer will run into the same problems as you did.

        moritz you are completely right as a "black-belt" language syntax guy. You like the ";" first solution because it fits your thought model of "how it works" - it is "obvious" to you as a expert - but what may be obvious to you may not be obvious to others.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-24 13:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found