Adam S
Adam S

Reputation: 9245

Why are some hashes initialized using curly braces, and some with parentheses?

I'm looking at the following code demonstrating nested hashes:

my %HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",  # Key quotes needed.
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);

Why is it that the upper-most hash (starting line 1) is initialized using parentheses, whereas the sub-hashes are initialized using curly braces?

Coming from a python background I must say Perl is quite odd :).

Upvotes: 21

Views: 8029

Answers (3)

ikegami
ikegami

Reputation: 386501

First, the parens do nothing but change precedence here. They never have nothing to do with list creation, hash creation or hash initialisation.

For example, the following two lines are 100% equivalent:

{   a => 1, b => 2   }
{ ( a => 1, b => 2 ) }

For example, the following two lines are 100% equivalent:

sub f { return ( a => 1, b => 2 ) }    my %hash = f(); 
sub f { return   a => 1, b => 2   }    my %hash = f(); 

Second, one doesn't initialise a hash using { }; one creates a hash using it. { } is equivalent to my %hash;, except that the hash is anonymous. In other words,

{ LIST }

is basically the same as

do { my %anon = LIST; \%anon }

(but doesn't create a lexical scope).

Anonymous hashes allows one to write

my %HoH = (
    flintstones => {
        husband   => "fred",
        pal       => "barney",
    },
    jetsons => {
        husband   => "george",
        wife      => "jane",
        "his boy" => "elroy",
    },
    simpsons => {
        husband   => "homer",
        wife      => "marge",
        kid       => "bart",
    },
);

instead of

my %flintstones = (
    husband   => "fred",
    pal       => "barney",
);
my %jetsons = (
    husband   => "george",
    wife      => "jane",
    "his boy" => "elroy", 
);
my %simpsons = (
    husband   => "homer",
    wife      => "marge",
    kid       => "bart",
);
my %HoH = (
    flintstones => \%flinstones,
    jetsons     => \%jetsons,
    simpsons    => \%simpsons,
);

Upvotes: 6

mob
mob

Reputation: 118665

Coming from a Perl background I find Perl quite odd, too.

Use parentheses to initialize a hash (or an array). A hash is a map between a set of strings and a set of scalar values.

%foo = ( "key1", "value1",  "key2", "value2", ... );   #  % means hash
%foo = ( key1 => "value1",  key2 => "value2", ... );   # same thing

Braces are used to define a hash reference. All references are scalar values.

$foo = { key1 => "value1", key2 => "value2", ... };    #  $ means scalar

Hashes are not scalar values. Since the values in a hash must be scalars, it is therefore not possible to use a hash as a value of another hash.

%bar = ( key3 => %foo );     # doesn't mean what you think it means

But we can use hash references as values of another hash, because hash references are scalars.

$foo = { key1 => "value1", key2 => "value2" };
%bar = ( key3 => $foo );
%baz = ( key4 => { key5 => "value5", key6 => "value6" } );

And that is why you see parentheses surrounding a list of lists with braces.

Upvotes: 31

justintime
justintime

Reputation: 3631

The essential difference (....) is used to create a hash. {....} is used to create a hash reference

my %hash  = ( a => 1 , b => 2 ) ;
my $hash_ref  = { a => 1 , b => 2 } ;

In a bit more detail - {....} makes an anonymous hash and returns a reference to it wich is asigned to the scalar $hash_ref

edited to give a bit more detail

Upvotes: 10

Related Questions