Possible Duplicate:
What's the best way to make a deep copy of a data structure in Perl?
I'm apparently misunderstanding something about how hashrefs work in Perl, and am here looking to correct that.
I need to get a copy of a hashref that I can fiddle with without modifying the original. According to my research, copying a hashref is just as simple as using the equals operator:
my $hashref_copy = $hashref;
But as far as I can tell, all that does is make $hashref_copy
a pointer to the original object. Consider this toy bit of code:
my $hashref = {data => "fish"}; my $hashref_copy = $hashref; $hashref_copy->{data} = "chips"; print "$hashref->{data}\n";
If $hashref_copy
were really an independent copy, I'd expect this code to print "fish". Instead, it prints "chips".
So either 1) I'm misunderstanding something or 2) Perl is broken. I'm quite certain it isn't #2, in spite of what my ego would have me think.
Where am I going wrong? And what do I need to do to make modifications to $hashref_copy
not show up in the original $hashref
?
You can create a shallow copy of a hash easily: my $copy = { %$source }; The %$source bit in list context will expand to the list of key value pairs. The curly braces (the anonymous hash constructor) then takes that list an creates a new hashref out of it.
A deep copy of an object is a copy whose properties do not share the same references (point to the same underlying values) as those of the source object from which the copy was made.
As the documentation for Storable shows dclone( ... ) is the equivalent of composition of thaw and freeze as thaw( freeze( ... )) . thaw can thaw any type of encoded structure. A reference can refer to anything in Perl. That array of hashes of arrays that you wanted, the hash of hashes of arrays, ....
When you copy a hashref into another scalar, you are copying a reference to the same hash. This is similar to copying one pointer into another, but not changing any of the pointed-to memory.
You can create a shallow copy of a hash easily:
my $copy = { %$source };
The %$source
bit in list context will expand to the list of key value pairs. The curly braces (the anonymous hash constructor) then takes that list an creates a new hashref out of it. A shallow copy is fine if your structure is 1-dimensional, or if you do not need to clone any of the contained data structures.
To do a full deep copy, you can use the core module Storable
.
use Storable 'dclone'; my $deep_copy = dclone $source;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With