开发者

Copying a hashref in Perl [duplicate]

开发者 https://www.devze.com 2023-03-28 18:13 出处:网络
This question already has answers here: Closed 10 years ago. Possible Duplicate: What's the best way to make a deep copy of a data structure in Perl?
This question already has answers here: Closed 10 years ago.

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 wh开发者_高级运维at 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?


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;


Yes, assignment just copies the reference (like copying a pointer value in other languages). What you're looking for is called a "deep copy".

Storable::dclone seems to be one solution (perldoc Storable for more information).

Clone is another (perldoc clone); thanks to Zaid for mentioning this in a comment.


If it's just a hash and all you're looking for is a copy of it:

my $hashref = {data => "a"};

my %hash_copy = %{$hashref}; # Create a copy of the hash that $hashref points to
my $hashref_copy = \%hash_copy; # Ref to %hash_copy
$hashref_copy->{data} = "b";

print "$hashref->{data}\n"; # Outputs 'a'
print "$hashref_copy->{data}\n"; # Outputs 'b'
0

精彩评论

暂无评论...
验证码 换一张
取 消