Steve May said:
how can you extract "mary" into another hash?
%a = ('mary'=>
{'address'=>11, 'zip'=>12},
'john'=>
{'address'=>21, 'zip'=>22},
);
%b = $a{'mary'}; ???
You are copying a reference above.
[...]
Reference found where even-sized list expected
Not really. Assigning a list to a hash causes the contents of the list
to be turned into key/value pairs as they're encountered, eg this code
[rw@sable]~#perl -e '%h = qw(a 1 b 2); print($h{a}, ", ", $h{b}, "\n")'
1, 2
causes %h to contain a key 'a' which is mapped to 1 and a key 'b' mapped
to 2. $a{mary} returns the value associated with the key 'mary' in the
hash %a. This is a reference to a hash. Since there's no other value,
this is effectively a list of size 1. An attempt to use a reference as
hash key will end up using the stringification of the reference instead,
consequently, what
%b = $a{mary}
does is create a key a la 'HASH(0x8195c70)' in %b whose corresponding
value is undef.
[...]
Copying the dereferenced value of 'mary' instead:
my %a = ('mary'=>
{'address'=>11, 'zip'=>12},
'john'=>
{'address'=>21, 'zip'=>22},
);
my %b = %{$a{'mary'}};
[...]
The outer brackets are not mandatory, but I tend to use them in
dereferencing as they are an immediate visual clue as to what the code
is doing.
They are mandatory in this case:
[rw@sable]~#perl -e '$h{a} = {h => a}; print %$h{a};'
syntax error at -e line 1, near "$h{a"
Execution of -e aborted due to compilation errors.
The exact rules are (quoted from memory) that a simple, scalar variable
holding a reference of the appropriate type can be used anywhere an
identifier could appear as well. Further, a block returning a reference
of an appropriate type can be used instead of the 'simple, scalar
variable'. Since $h{a} is not a scalar variable, %$h{a} is a syntax
error and the second form has to be used instead which is
%{$h{a};}
when written in full. Since the semicolon can be omitted after the last
statement in a block, this can also be written as
%{$h{a}}
It is usually more convenient to use the ->-dereferencing operator
instead of the 'block returning a reference' construct where possible,
eg (showing all three ways to get the value associated with 'a' in the
hash $h refers to):
[rw@sable]~#perl -e '$h = { a => 3 }; print(join(", ", $$h{a}, ${$h}{a}, $h->{a}), "\n")'
3, 3, 3