Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Difference in Hash Declaration

by perl@1983 (Sexton)
on May 07, 2012 at 07:00 UTC ( #969193=perlquestion: print w/ replies, xml ) Need Help??
perl@1983 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, Can someone please help to clarify what is the difference between below three declarations (please note the brackets):
Example 1:
my %h = { ( 1 => "j", 2 => "b", ), ( 1 => "p", 2 => "b", ), };
Example 2:
my %h = ( ( 1 => "j", 2 => "b", ), ( 1 => "p", 2 => "b", ), );
Example 3:
my %h = { { 1 => "j", 2 => "b", }, { 1 => "p", 2 => "b", }, };
Thanks in advance.

Comment on Difference in Hash Declaration
Select or Download Code
Re: Difference in Hash Declaration
by Anonymous Monk on May 07, 2012 at 07:17 UTC

    Say it with me:

    { 'hashes', 'are', 'curly', 'ones' }

    [ 'arrays', 'are', 'square' ]

    ( 'lists are round' )

    using and understanding strict/warnings cuts your development time in half!

    #!/usr/bin/perl -- use strict;use warnings; use Data::Dump qw/ dd /; my %ro = { ( 1 => "j", 2 => "b", ), ( 1 => "p", 2 => "b", ), }; my %sham = ( ( 1 => "j", 2 => "b", ), ( 1 => "p", 2 => "b", ), ); my %bo = { { 1 => "j", 2 => "b", }, { 1 => "p", 2 => "b", }, }; dd \%ro; dd \%sham; dd \%bo; __END__ Reference found where even-sized list expected at - line 4. Reference found where even-sized list expected at - line 28. { "HASH(0x3f8c64)" => undef } { 1 => "p", 2 => "b" } { "HASH(0x99a3bc)" => undef }
      Thanks. This is useful.
Re: Difference in Hash Declaration
by tobyink (Abbot) on May 07, 2012 at 07:23 UTC

    The difference is that Example 2 (using parentheses) is correct and the others are broken.

    Braces (i.e. { and }) are used (amongst other things) to create hash references. So...

    my %hash = ( foo => 1, bar => 2 ); my $hashref = { foo => 1, bar => 2 };
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Difference in Hash Declaration
by moritz (Cardinal) on May 07, 2012 at 07:23 UTC

    Round parens don't create any substructures. Curly braces create hash references, see perlreftut.

    Putting a hash reference in a position where a hash key is expected doesn't make any sense, because it is converted to a string which loses all the interesting information that way.

Re: Difference in Hash Declaration
by anazawa (Beadle) on May 07, 2012 at 08:13 UTC
    Parenthesis () creates LIST:
    ( 1 => 'j', 2 => 'b' )
    To create a hash, we substitute the LIST for %h:
    my %h = ( 1 => 'j', 2 => 'b' );
    Incidentally, LIST is different from ARRAY. To create an array, we substitute LIST for @a:
    my @a = ( 1 => 'j', 2 => 'b' );
      Parenthesis () creates LIST:
      print 1, 'b', 3, 'd', 5, 'f', "\n";

      I see a list there but I don't see any parentheses.

      my @stuff = map $_ + 2, 6, 7, 8, 9, 10;

      Ditto

      Parentheses are used for precedence.

      my %h = ( 1 => 'j', 2 => 'b' );

      There the assignment operator has higher precedence than the comma operator so the parentheses are required.

        I agree with you. Parentheses don't create LIST, are used for precedence. I'm glad you pointed out my mistake :)
Re: Difference in Hash Declaration
by jwkrahn (Monsignor) on May 07, 2012 at 11:25 UTC

    A list can only contain scalar values, for example: ( 1, 'a', [], {}, sub{}, $scalar, \$scalar, \@array, \%hash, \&subroutine, \*type_glob ), (a number, a string, an anonymous array, an anonymous hash, an anonymous subroutine, a scalar variable, a reference to a scalar variable, a reference to an array, a reference to a hash, a reference to a subroutine, a reference to a type glob.)

    In Example 1 you are assigning an anonymous hash to an hash, which is the same as saying my %h = {}; or my %h = 'a'; or my %h = 1;.    You need to assign a list with an even number of elements.

    In Example 2 you are assgning a list of eight elements to the hash.    Unfortunately two of the keys are the same as the other two keys so only the last two unique keys are saved to the hash.

    Example 3 is basically the same as Example 1.

      Thank you very much...that was helpful.
Re: Difference in Hash Declaration
by MidLifeXis (Prior) on May 07, 2012 at 13:47 UTC

    The only one that is syntactically valid is the second one, however, I don't believe that it is doing what you are expecting. Since the parens denote precedence, what Perl reads it as is:

    my %sham = ( 1 => "j", 2 => "b", 1 => "p", 2 => "b", );

    When assigning to hashes, later insertions with the same key end up replacing any earlier entries with the same key, leaving you with:

    my %sham = ( 1 => "p", 2 => "b", );

    This can be shown with the use of Data::Dumper or the like. I think what you are intending is:

    my @sham = ( # note the sigil { 1 => "j", 2 => "b", }, { 1 => "p", 2 => "b", }, );

    Data::Dumper (and any similar module) is a useful tool for visualizing nested data structures.

    --MidLifeXis

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://969193]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2014-07-12 13:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (240 votes), past polls