Почему некоторые хеши инициализируются с помощью фигурных скобок, а некоторые с круглыми скобками?

Я просматриваю следующий код, демонстрирующий вложенные хэши:

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",
    },
);

Почему это то, что верхний самый хэш (начальная строка 1) инициализируется с помощью круглых скобок, тогда как субахели инициализируются с помощью фигурных скобок?

Исходя из фона python, я должен сказать, что Perl довольно странно:).

Ответы

Ответ 1

Исходя из фона Perl, я считаю, что Perl тоже довольно странный.

Используйте скобки для инициализации хэша (или массива). Хэш - это карта между множеством строк и множеством скалярных значений.

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

Брекеты используются для определения хеш-ссылки. Все ссылки являются скалярными значениями.

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

Хеши не являются скалярными значениями. Поскольку значения в хэше должны быть скалярами, поэтому невозможно использовать хеш в качестве значения другого хэша.

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

Но мы можем использовать хеш-ссылки как значения другого хэша, так как хеш-ссылки являются скалярами.

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

И вот почему вы видите круглые скобки, содержащие список списков с фигурными скобками.

Ответ 2

Существенное различие (....) используется для создания хэша. {....} используется для создания хеш-ссылки

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

Немного подробнее - {....} создает анонимный хеш и возвращает ссылку на него, которая присваивается скалярному $hash_ref

отредактирован, чтобы дать немного подробнее

Ответ 3

Во-первых, параны ничего не делают, кроме как превалируют здесь. Они никогда не имеют никакого отношения к созданию списка, созданию хэша или инициализации хэша.

Например, следующие две строки эквивалентны на 100%:

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

Например, следующие две строки эквивалентны на 100%:

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

Во-вторых, не инициализировать хеш с помощью { }; один создает хэш, используя его. { } эквивалентно my %hash;, за исключением того, что хеш является анонимным. Другими словами,

{ LIST }

в основном совпадает с

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

(но не создает лексическую область).

Анонимные хэши позволяют писать

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

вместо

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,
);