Of course you can pass by value & make changes sans changes to original reference via dereference ...
#!/perl
use warnings; use strict; use 5.010;
my $got = throw_ref();
my %hash = change_hash( %{ $got } );
say 'original hash now ...';
show_hash( %{ $got } );
exit;
sub change_hash
{
my ( %h ) = @_;
say 'before modification ...';
show_hash( %h );
$h{'p'} += 10;
$h{'q'} = 3;
say 'after modification ...';
show_hash( %h );
return %h;
}
sub show_hash
{
my ( %h ) = @_;
printf "%s : %s\n" , $_ , $h{ $_ } for sort keys %h;
return;
}
sub throw_ref
{
return { 'p' => -2 } ;
}
__END__
before modification ...
p : -2
after modification ...
p : 8
q : 3
original hash now ...
p : -2
... But if the hash reference is big and/or tied, then dereference could be expensive and/or undesired.