Perl deep clone and recursive hash merge

Perl
use strict;
use warnings;
use Storable qw(dclone);

sub deep_merge {
    my ($base, $over) = @_;
    return dclone($over) if ref $over ne 'HASH';
    my %out = %{ dclone($base) };
    for my $key (keys %$over) {
        my ($a, $b) = ($out{$key}, $over->{$key});
        $out{$key} = ref $a eq 'HASH' && ref $b eq 'HASH' ? deep_merge($a, $b) : dclone($b);
    }
    return \%out;
}

my $defaults = { db => { host => 'localhost', port => 5432 }, debug => 0 };
my $merged = deep_merge($defaults, { db => { port => 6543 } });
print "$merged->{db}{host}:$merged->{db}{port}\n";