Your problem is that you didn't
localize
$_ in the sub. As a result, the
$_ from the outside world is changed. And since parameters are passed by reference, your parameter is changed
after you passed it in.
"$_" passes a copy, so that one doesn't change.
As a fix, which IMO is much less interesting than the phenomenon we just witnessed,
you can localize the change by
sub foo
{
while (@_) { local $_ = shift; $params->{$_} = shift; }
print "$_: $params->{$_}\n", for keys %$params;
}
or
sub foo
{
local $_;
while (@_) { $_ = shift; $params->{$_} = shift; }
print "$_: $params->{$_}\n", for keys %$params;
}