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 undefined 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_depth)); } 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 conveniently\n"; }