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

Hello,

I tried to understand why the following (with map sentence) gives an error. Can't understand.
use warnings; use strict; @_ = 'a' .. 'c'; print @_[ map $_ -1, grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
Missing comma after first argument to map function at map_inside_splic +e.pl line 12, near "]"
And the following (with map block) don't give an error:
use warnings; use strict; @_ = 'a' .. 'c'; print @_[ map {$_ -1} grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
OUTPUT:
a
upd: thanks for answers below.

Replies are listed 'Best First'.
Re: map sentence as array slice indexes
by BrowserUk (Patriarch) on Nov 25, 2015 at 12:08 UTC
    I tried to understand why the following (with map sentence) gives an error.

    The not-very-helpful answer is: because you've created an ambiguous state in the parser.

    It can be avoided by:

    • Omitting the space: print @a[ map $_-1, grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
    • Or using a unary plus prefix: print @a[ map +$_ -1, grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];
    • Or (as you've identified) using the block form: print @a[ map{ $_ -1 } grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1 .. 1 ];

    My guess is that because the parser fails to find a comma following the first argument ($_) to map, it attempts to treat that first argument as a block, and gets confused.

    Under 5.10 I get: panic: ck_grep at ...; but that panic seems to have been replaced with the error message you get in later versions.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: [closed] map sentence as array slice indexes
by Discipulus (Canon) on Nov 25, 2015 at 12:09 UTC
    Hello,
    in the docs for map i read:
    { 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 + or semicolon to give Perl some help:
    So you need to help Perl doing the right guess, using a plus sign (and parentheses!):
    use warnings; use strict; @_ = 'a' .. 'c'; print @_[ map +($_ -1), grep { $_ > 0 and $_ <= 1 } map { $_ + 1 } -1..1 ];

    HtH
    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.