The difference is that the assignment of %h1 completely wrong, and the assignment of %h2 almost correct.
Perl uses parentheses to create a list that can be assigned to an array or hash:
@a = (1, 2, 3); %a = (foo => 'bar', 7 => 3);
Perl uses parentheses to create a list link that can be assigned to a scalar.
$a = [ 1, 2, 3 ];
Perl uses curly braces to create a hash link that can be assigned to a scalar.
$a = { key1 => 1, key2 => 2 };
Another important point to keep in mind is that hash table values ​​are always scalars. Perl does not have “hashes of lists”, “hashes of hashes” - these are convenience conditions that really mean “hashes of list links” and “hashes of hash links”.
With this in mind, let's look at your examples:
%h1 = { ... };
already mistaken. The brackets create a hash link, which is considered as a single scalar, and what you do is equivalent to this:
$scalar = { ... }; %h1 = ( "$scalar" => undef );
therefore %h1 contains one key with an ugly name, like HASH(0x54321098) , and not what you mean. Say instead
%h1 = ( ... )
Moving
%h1 = ( 'key1' => ( 1, 2, 3 ), 'key2' => ( 4, 5, 6 ) );
also doesn't do what looks like what you want to do. This assignment has lists, not links to lists, and another thing to keep in mind is that Perl "smooths" the lists. If you think of => as a pretty synonym for a comma (which is almost true), you will see that this assignment is equivalent to either:
%h1 = ( 'key1', 1, 2, 3, 'key2', 4, 5, 6 );
or
%h1 = ( 'key1' => 1, 2 => 3, 'key2' => 4, 5 => 6 );
creating a hash table with four key pairs, not two expected.
If we fix the braces around the destination %h2 , then
%h2 = ( key1 => [ 1, 2, 3 ], key2 => [ 4, 5, 6 ] );
will do what you expect. Remember that hash table values ​​must be scalars and that a list reference is a scalar. Then you can say something like $h2{'key1'}[1] to get individual list items (in this case 2).