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

Hello Monks,

Would someone please explain to me why the following two hash initializations react differently?

Specifically, the QUOTEDSALES assignment is parenthesized in the second, but not in the first.

The indication that I'm seeing is that the last four keys are missing (using the first init) after subsequent processing...

I had drawn the erroneous conclusion that it doesn't matter if parentheses are included or omitted. Would someone please explain the rule that should be applied here?

my $item = { JOBN => $record->[0], CUSTOMERN => $record->[1], JOBDESCRIPTION => $record->[2], QUANTITY => $record->[3], QUOTEDSALES => sprintf "%0.2f", $record->[4] * 0.04, DUEDATE => $record->[5], PRODPLANNER => '5', PRODUCTCODE => '900', SALESMANN => '48', };
my $item = { JOBN => $record->[0], CUSTOMERN => $record->[1], JOBDESCRIPTION => $record->[2], QUANTITY => $record->[3], QUOTEDSALES => sprintf("%0.2f", $record->[4] * 0.04), # <-- NOT +E parens DUEDATE => $record->[5], PRODPLANNER => '5', PRODUCTCODE => '900', SALESMANN => '48', };

Where do you want *them* to go today?

Replies are listed 'Best First'.
Re: Odd behavior in hash initialization due to missing parens
by GrandFather (Saint) on Oct 08, 2007 at 23:02 UTC

    printf/sprintf take a list of arguments. In the first case sprintf gobbles up all the remaining items in the hash initialization list (even though the format string doesn't require them). In the second case the list that sprintf sees is constrained by the parens.

    Note that => and , (comma) are in essence the same except that => stringizes the item to the left of it.


    Perl is environmentally friendly - it saves trees
      Perfect. Thanks++

      Where do you want *them* to go today?
Re: Odd behavior in hash initialization due to missing parens
by ysth (Canon) on Oct 09, 2007 at 05:56 UTC
    What GrandFather said.

    Deparse is your friend (though in this case, it needs a little perltidy help to be readable):

    $ perl -MO=Deparse,-p|perltidy my $item = { JOBN => $record->[0], CUSTOMERN => $record->[1], JOBDESCRIPTION => $record->[2], QUANTITY => $record->[3], QUOTEDSALES => sprintf "%0.2f", $record->[4] * 0.04, DUEDATE => $record->[5], PRODPLANNER => '5', PRODUCTCODE => '900', SALESMANN => '48', }; - syntax OK ( my $item = { 'JOBN', $$record[0], 'CUSTOMERN', $$record[1], 'JOBDESCRIPTION', $$record[2], 'QUANTITY', $$record[3], 'QUOTEDSALES', sprintf( '%0.2f', ( $$record[4] * 0.04 ), 'DUEDATE', $$record[5], 'PRODPLANNER', '5', 'PRODUCTCODE', '900', 'SALESMANN', '48' ) } );
Re: Odd behavior in hash initialization due to missing parens
by naikonta (Curate) on Oct 09, 2007 at 10:21 UTC
    Welcome to the greediness of list construct.

    The commas in the hash are pair separator. After the sprintf they become argument separator for sprintf, and without the parens it lasts until the last scalar (48 in this case). With parens, the commas as argument separator for sprintf are only before the closing paren. The closing paren itself acts as argument terminator for sprintf, separating it as an execution unit from the rest of the pairs. After the closing paren, commas become pair separator again.


    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: Odd behavior in hash initialization due to missing parens
by FunkyMonk (Bishop) on Oct 08, 2007 at 22:55 UTC
    Mostly guessing, but does the fat comma have the same precedance as a normal comma (I think it does)?