Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

(5.6.1) map mayhem?

by jynx (Priest)
on Oct 07, 2003 at 19:43 UTC ( [id://297370]=perlquestion: print w/replies, xml ) Need Help??

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


In Perl 5.6.1, writing out a little test script i got my error to one little line. Here's the entire script to start with:
#!/usr/bin/perl -w use strict; my @one = qw( one two three ); my $two = sub { print "we were passed @_\n" }; # here's the problem line: $two->( map { anda => $_ } @one ); # But this would work fine: #$two->( map { 1 && anda => $_ } @one );

When compiling that as is Perl bails on a syntax error. The second (more ugly) version works fine, as well as using a variable instead of a hard-coded string. That's fine and good, but why is it happening that way?

i would think one would be able to code as i have above, but (on a Solaris 9 machine running the standard Perl 5.6.1 Sun install) apparently not. If i add parentheses i find out that apparently Perl is viewing { anda => $_ } as a hash reference, but map is expecting a code reference, so that's probably where the discrepency comes from.

Questions:

  1. Is there some nuance in the code i'm missing that will make it be short and readable instead of adding ugly hacks to get map to read that as a code block instead of a hash reference?
  2. Is anyone else having this problem? Or is it just me?
  3. Assuming it's standard behavior from 5.6.1, is it fixed in 5.8?
thanks for any and all help...

jynx

Replies are listed 'Best First'.
Re: (5.6.1) map mayhem? (+{ {;)
by tye (Sage) on Oct 07, 2003 at 20:02 UTC

    When Perl sees an open brace ({) that isn't part of some construct (like $hash{$key}), it sometimes isn't sure whether it is meant to start a block or an anonymous hash reference. You can tell Perl which you meant by using +{ for anonymous hash reference and {; for a block.

    You are trying to pass a block to map so you can change the problematic line to:

    $two->( map {; anda => $_ } @one );
    which is a bit ugly.

                    - tye
      IMO Perl should always interpret an opening brace right after the map and grep keywords, as the start of a block. There's no excuse for it, preferring to treat it as an anonymous hash.

      Do you ever think you're seeing an anonymous hash in that position? I didn't think so.

        That might be the obvious case in hindsight. But you can't change the DWIMmery radically now, without having something subtly being made different. Also, I think it's the same DWIMmery used at the beginning of a statement that might also be a return value for a subroutine: you sometimes want that to be a block, and sometimes and hashref, hence the DWIMmery.

        Personally, I find the "+" prefix and ";" suffix to that open brace a bit tacky, but certainly a lot better than having a language force me to always use 8-space tabs just to make sure that lined up things stay lined up since the lineup is syntactically significant. {grin}

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

        If you're me you do. I rarely ever use blocks with map - if I've got braces then its going to be a hash (though the dwimmery forces me to prepend a '+' to make it behave).

Re: (5.6.1) map mayhem?
by jasonk (Parson) on Oct 07, 2003 at 19:54 UTC

    1. Is there some nuance in the code i'm missing that will make it be short and readable instead of adding ugly hacks to get map to read that as a code block instead of a hash reference?

    The easiest/cleanest way seems to be to add parens around the contents... $two->( map { (anda => $_) } @one );.

    2. Is anyone else having this problem? Or is it just me?

    Your code broke for me as well

    3. Assuming it's standard behavior from 5.6.1, is it fixed in 5.8?

    I get the same results from 5.8.0.


    We're not surrounded, we're in a target-rich environment!
Re: (5.6.1) map mayhem?
by eric256 (Parson) on Oct 08, 2003 at 15:40 UTC

    Personlay I think

    $two->( map { (anda => $_) } @one );

    is a bit clearer to read. Just my 2cents :-)


    ___________
    Eric Hodges

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://297370]
Approved by diotalevi
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-19 15:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found