dragonchild has asked for the wisdom of the Perl Monks concerning the following question:

Before I go re-invent the wheel, does anyone know of a module/snippet that will take a scalar (reference or not) and return a copy of it? This doesn't sound so hard, but I want to copy anything within it, so a hash of lists of hashes, when copied, should make a copy of the hash. That new hashref should point to listrefs that are different than the original's. And, those listrefs should point to hashrefs that have been copied, as well.

Replies are listed 'Best First'.
Re: Recursive copier
by btrott (Parson) on Jun 18, 2001 at 21:48 UTC
    You could get the effect of a deep copy by serializing and deserializing a data structure, using some method of serialization. Eg. Data::Dumper or Storable.

    Or you could also investigate the Clone module, which I've not seen before but which is on CPAN. It looks like it should do what you want:

    use Clone qw(clone); my $b = clone($a);
Re: Recursive copier
by extremely (Priest) on Jun 19, 2001 at 01:26 UTC
    Best way, period, is:
    use Storable qw(dclone); # Deep (recursive) cloning $cloneref = dclone($ref);

    Keeping in mind it is shipped for free with any fairly modern perl installation (INST_FILE /usr/local/lib/perl5/site_perl/5.6.0/i686-linux/ and is one of the more regularly "use"d modules in other modules. That means the perl-porters themselves have taken a modicum of interest in seeing that it is correct and complete.

    The likelyhood is, you already have Storable installed!

    $you = new YOU;
    honk() if $you->love(perl)

Re: Recursive copier
by dimmesdale (Friar) on Jun 18, 2001 at 21:39 UTC
    {I hope this works; it appears PM is having problems today; my browser keeps saying that the page doesn't exist}

    Well, what you are saying sounds familiar(in C/C++ it happens a lot w/ classes, and is called shallow vs. deep copying). I don't know of any modules that have this, but I can give you some advice:

    (1)Recursive is definately the way to go
    (2)Make variables lexically scoped, i.e., with *my*; perl won't delete these variables if there's a ref. to them, but if the funtion's called again(e.g., recursively) it'll create a new copy of them
    (3)Post your code here if you have any problems

Re: Recursive copier
by DrZaius (Monk) on Jun 18, 2001 at 22:29 UTC
    Hehe, after a comment from btrott and a cold shower I realized I answered the wrong question. Oh well :) You probably don't need recursion in your algo if you use a File::Copy/File::Find combo like this:
    use strict; use File::Copy qw/copy/; use File::find qw/find/; sub rcopy { my $src = shift; my $dst = shift; find(sub { my ($src_file, $dst_file) = ($File::Find::fullname, $File::Find::fullname); $dst_file =~ s!^$src!$dst!; copy $src_file, $dst_file or die "Could not copy $src_file => $dst_file:$!"; }, $src); }