Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying a hashref in Perl [duplicate]

Tags:

perl

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?

like image 809
BlairHippo Avatar asked Aug 16 '11 18:08

BlairHippo


People also ask

How to copy a hash in Perl?

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.

What is a deep copy?

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.

What is Dclone in Perl?

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, ....


1 Answers

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; 
like image 95
Eric Strom Avatar answered Oct 17 '22 19:10

Eric Strom