The snippet I'm pasting in below may help. The trick to upgrading it to do deep copies of circular structures is to store the parts already worked out in a hash and look them up before deep copying, then use any previously created part of the deep copy instead of making a fresh one - a sort of poor man's memoising. But I haven't had to do that yet, so I only put in a check count to prevent recursing too deep. Oh, and obviously it doesn't yet handle all possible types, just the ones I needed in my application. PML.
sub deep_copy {
# this subroutine returns a deep copy of the specified reference
# it cannot cope with circular structures yet
my $ref_prm = shift;
my $remaining_depth = (shift) - 1;
return undef if (not defined($ref_prm)); # allowed to be undefined
my $ref_type = ref($ref_prm);
if ($remaining_depth < 0) {
warn "Excessive call depth, possible circular structure - " .
"deep copy failing\n";
return undef;
}
return $ref_prm if (not $ref_type); # something, and will not be un
+defined
if ($ref_type eq "REF") {
my $deeper_copy_ref = deep_copy($$ref_prm, $remaining_depth); #
+recursive call
return \$deeper_copy_ref;
}
if ($ref_type eq "SCALAR") {
my $deeper_copy_scalar = $$ref_prm;
return \$deeper_copy_scalar;
}
if ($ref_type eq "ARRAY") {
my @deeper_copy_array = ();
foreach my $copy_value (@$ref_prm) { # recursive calls
push(@deeper_copy_array, deep_copy($copy_value, $remaining_de
+pth));
}
return \@deeper_copy_array;
}
if ($ref_type eq "HASH") {
my %deeper_copy_hash = ();
foreach my $copy_key (keys %$ref_prm) { # recursive calls
$deeper_copy_hash{$copy_key} = deep_copy($ref_prm->{$copy_key
+},
$remaining_depth);
}
return \%deeper_copy_hash;
}
die "There is something in $ref_prm that cannot be deep copied conv
+eniently\n";
}