use Data::Dumper;
sub func_A{my $H=shift();$H={key=>'val_A'}}
sub func_B{my $H=shift();%$H=(key=>'val_B')}

my $H={};
func_A($H);
print Dumper $H; # $H={} 変更されない
func_B($H);
print Dumper $H; # $H={key=>'val_B'} 変更される

上記の理由がよくわからないのですが、どう理解すればいいのでしょう?