sub iterative_copy { my $root; my @todo; push @todo, [ $_[0], \$root ]; while (@todo) { my ($src, $dst) = @{ shift(@todo) }; if (not ref $src) { $$dst = $src; } elsif (ref $src eq "HASH") { $dst = ($$dst = {}); push @todo, map { [ $src->{$_}, \($dst->{$_}) ] } keys %$src; } elsif (ref $src eq "ARRAY") { $dst = ($$dst = []); push @todo, map { [ $src->[$_], \($dst->[$_]) ] } 0..$#$src; } else { Carp::croak "What's a " . ref $_ . "?" } } return $root; }