sub _copy { my $this = shift; if (not ref $this) { $this } elsif (ref $this eq "HASH") { +{map { $_ => _copy($this->{$_})} keys %$this} } elsif (ref $this eq "ARRAY") { [map _copy($_), @$this] } elsif (ref $this eq "CODE") { # do some processing here, the following is a # placeholder 'CODEREF' } else { Carp::croak "What's a " . ref $_ . "?" } } #### sub _iterative_copy { my $this = shift; my @pile = $this; my $this_new = {}; my $root = $this_new; my @pile_new = $this_new; while (defined($this = shift @pile)) { $this_new = shift @pile_new; if (ref $this eq "HASH") { for (keys %$this) { if (ref (my $v = $this->{$_})) { if (ref $v eq "HASH") { $this_new->{$_} = {} } elsif (ref $v eq "ARRAY") { $this_new->{$_} = [] } elsif (ref $v eq "CODE") { # do some processing here, # the following is a placeholder $this_new->{$_} = "CODEREF" } else { Carp::croak "What's a " . ref $v } unshift @pile, $v; unshift @pile_new, $this_new->{$_}; } else { $this_new->{$_} = $v } } } # quietly ignore coderefs, # they are dealt with in the inner loop elsif (ref $this ne "CODE") { Carp::croak "What's a " . ref $this } } $root;