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

前端 未结 3 394
予麋鹿
予麋鹿 2021-02-05 08:42

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

my %HoH = (
    flintstones => {
        husband   => \"fred\",
        pal       => \"b         


        
相关标签:
3条回答
  • 2021-02-05 09:22

    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

    0 讨论(0)
  • 2021-02-05 09:24

    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.

    0 讨论(0)
  • 2021-02-05 09:24

    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,
    );
    
    0 讨论(0)
提交回复
热议问题