Copying Data Structures (Perl Cookbook, 2nd Edition)

## 11.12. Copying Data Structures

### 11.12.1. Problem

You need to copy a complex data structure.

### 11.12.2. Solution

Use the `dclone` function from the standard Storable module:

>     use Storable;

>     $r2 = dclone($r1);

### 11.12.3. Discussion

Two types of "copy" are sometimes confused. A surface copy (also known as shallow copy) simply copies references without creating copies of the data behind them:

>     @original = ( \@a, \@b, \@c );
>     @surface = @original;

A deep copy creates an entirely new structure with no overlapping references. This copies references to one layer deep:

>     @deep = map { [ @$_ ] } @original;

If `@a`, `@b`, and `@c` themselves contain references, the preceding `map` is no longer adequate. Writing your own code to deep-copy structures is laborious and rapidly becomes tiresome.

The Storable module provides a function called `dclone` that recursively copies its argument:

>     use Storable qw(dclone);
>     $r2 = dclone($r1);

This only works on references or blessed objects of type SCALAR, ARRAY, HASH, or CODE;[20] references of type GLOB, IO, and the more esoteric types are not supported. The `safeFreeze` function from the FreezeThaw module supports even these types when used in the same address space by using a reference cache that could interfere with garbage collection and object destructors under some circumstances.

> [20]Believe it or not, it's true. Storable can even serialize closures. See its manpage for how to unthaw these using a Safe compartment.

Because `dclone` takes and returns references, you must add extra punctuation if you have a hash or arrays to copy:

>     %newhash = %{ dclone(\%oldhash) };

### 11.12.4. See Also

The documentation for the standard Storable and Data::Dumper modules, and for the FreezeThaw CPAN module.

Copyright © 2003 O'Reilly & Associates. All rights reserved.