use Scalar::Util qw(reftype); sub copy_and_prune { my $item = shift; return $item unless defined ref($item); if (reftype($item) eq 'HASH') { if (1 == keys %$item) { # return the one value here } else { my %ret; while (my ($key, $value) = each %$item) { $ret{$key} = copy_and_prune($value); } return \%ret; } } elsif ( # other cases ... }