$hash{a}{drinks}=1;
$hash{b}{drinks}=2;
as a single hash, but that's not the case. There are three:
- %hash
- %{ $hash{a} }
- %{ $hash{b} }
+-------+ +----------+ +-----------+ +-------------+
| %hash | +-->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+-------+ | +----------+ | +-----------+ | +-------------+
| a ----+ | addr ----+ | drinks ----+ | 1 |
| b -----+ +----------+ +-----------+ +-------------+
+-------+ |
| +----------+ +-----------+ +-------------+
+->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+----------+ | +-----------+ | +-------------+
| addr ----+ | drinks ----+ | 2 |
+----------+ +-----------+ +-------------+
When you do %copy = %hash (which you wrote as %copy = %{ \%hash }), you are copying the keys and values of %hash. So what are the keys and values of %hash?
>perl -e"$h{a}{d}=1; $h{b}{d}=2; print qq{$_: $h{$_}\n} for keys %h;"
a: HASH(0x22534c)
b: HASH(0x2253a0)
That's all that's copied, nothing more. It will not make a copy of the referenced value and make a new reference to it. It simply copies the references. You end up with
+-------+ +----------+ +-----------+ +-------------+
| %hash | +-->| Anon Ref | +----->| Anon hash | +->| Anon scalar |
+-------+ | +----------+ | +-----------+ | +-------------+
| a ----+ | addr -----+ | drinks ----+ | 1 |
| b -----+ +----------+ | +-----------+ +-------------+
+-------+ | |
| +----------+ | +-----------+ +-------------+
+->| Anon Ref | | +-->| Anon hash | +->| Anon scalar |
+----------+ | | +-----------+ | +-------------+
| addr --------+ | drinks ----+ | 2 |
+----------+ | | +-----------+ +-------------+
| |
+-------+ +NEW-------+ | |
| %copy | +-->| Anon Ref | | |
+-------+ | +----------+ | |
| a ----+ | addr -----+ |
| b -----+ +----------+ |
+-------+ | |
| +NEW-------+ |
+->| Anon Ref | |
+----------+ |
| addr --------+
+----------+
What you want is to do is to copy referenced values as well, and to do recursively, so that you end up with the following:
+-------+ +----------+ +-----------+ +-------------+
| %hash | +-->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+-------+ | +----------+ | +-----------+ | +-------------+
| a ----+ | addr ----+ | drinks ----+ | 1 |
| b -----+ +----------+ +-----------+ +-------------+
+-------+ |
| +----------+ +-----------+ +-------------+
+->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+----------+ | +-----------+ | +-------------+
| addr ----+ | drinks ----+ | 2 |
+----------+ +-----------+ +-------------+
+-------+ +NEW-------+ +NEW--------+ +NEW----------+
| %copy | +-->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+-------+ | +----------+ | +-----------+ | +-------------+
| a ----+ | addr ----+ | drinks ----+ | 1 |
| b -----+ +----------+ +-----------+ +-------------+
+-------+ |
| +NEW ------+ +NEW--------+ +NEW----------+
+->| Anon Ref | +->| Anon hash | +->| Anon scalar |
+----------+ | +-----------+ | +-------------+
| addr ----+ | drinks ----+ | 2 |
+----------+ +-----------+ +-------------+
That's called a "deep copy" because it copies every level of the data structure. In contrast, a simple assignment is called a "shallow copy" because it only copies the immediate value (scalar/hash/array/...).
|