What's the best way to make a deep copy of a data structure in Perl?
Asked Answered
K

5

42

Given a data structure (e.g. a hash of hashes), what's the clean/recommended way to make a deep copy for immediate use? Assume reasonable cases, where the data's not particularly large, no complicated cycles exist, and readability/maintainability/etc. are more important than speed at all costs.

I know that I can use Storable, Clone, Clone::More, Clone::Fast, Data::Dumper, etc. What's the current best practice?

Kimble answered 23/12, 2008 at 4:38 Comment(2)
Is deep-copy really irrelevant, @JasonMArcher? The summary talks about C and C++, but shallow and deep copy are language-agnostic concepts. By a clone, shallow copy is usually meant (Java, C#, …), this question is asking for a deep copy.Zeeland
Our tags don't need to git into minutiae. These are all kinds of cloning operations. Currently we have [clone], [cloning], [copy], [deepclone], [deep-clone], [deep]+[clone], [deep]+[copy] and [deep-copy].Trombley
G
19

Clone is much faster than Storable::dclone, but the latter supports more data types.

Clone::Fast and Clone::More are pretty much equivalent if memory serves me right, but less feature complete than even Clone, and Scalar::Util::Clone supports even less but IIRC is the fastest of them all for some structures.

With respect to readability these should all work the same, they are virtually interchangeable.

If you have no specific performance needs I would just use Storable's dclone.

I wouldn't use Data::Dumper for this simply because it's so cumbersome and roundabout. It's probably going to be very slow too.

For what it's worth, if you ever want customizable cloning then Data::Visitor provides hooking capabilities and fairly feature complete deep cloning is the default behavior.

Gollin answered 24/12, 2008 at 3:54 Comment(1)
Do you have a link to Scalar::Util::Clone? I can't find it on either CPAN or Metacpan...Escape
M
16

My impression is that Storable::dclone() is somewhat canonical.

Molly answered 23/12, 2008 at 4:47 Comment(0)
F
8

Clone is probably what you want for that. At least, that's what all the code I've seen uses.

Friulian answered 23/12, 2008 at 6:8 Comment(0)
O
1

Try to use fclone from Panda::Lib which seems the fastest one (written in XS)

Oster answered 1/2, 2019 at 18:33 Comment(4)
Clone and Storable are all written in XS. What do you mean by "seems the fastest one"?Fourthclass
Panda::Lib doesn't build on Windows, which limits its usefulness.Fourthclass
please, see the benchmarks at gist.github.com/jef-sure/ef8849e6abbeb9b8aac74c71389886f7Oster
Try to file a bug report, if you need to let it work on Windows. AFAIK, it is actively maintained.Oster
R
-1

Quick and dirty hack if you're already dealing with JSONs and using the JSON module in your code: convert the structure to a JSON and then convert the JSON back to a structure:

use JSON;

my %hash = (
    obj => {},
    arr => []
);

my $hash_ref_to_hash_copy = from_json(to_json(\%hash));

The only negative possibly being having to deal with a hash reference instead of a pure hash, but still, this has come in handy a few times for me.

Ruysdael answered 1/12, 2021 at 11:26 Comment(1)
The major limiting factor for JSON serialization is that it can't handle blessed references (or the class has to handle serialization in some way). If blessed references aren't part of the data, this might be fine.Insanity

© 2022 - 2024 — McMap. All rights reserved.