in reply to Modifying hash keys via aliasing

Although you have already been given detailed answers, just one quick question to let you think about it: if you passed an array to your sub, you would not expect it to modify the array subscripts, would you?

Admittedly, it is not quite exactly the same, but you don't need a sub to figure out that you simply cannot modify the keys of a hash (other than by deleting an existing entry and creating another one.

What is happening in your sub is that the values associated with the hash keys are actually modified in @_, but this has no effect on the hash itself, whereas the values associated with the hash values are actually modified within the hash, as it can be seen with this slight modification of your one-liner:

$ perl -MData::Dumper -we 'sub t{ $_+=1 for @_; print Dumper \@_;} my + %h = (1 => 2, 3 => 4); t(%h); print Dumper \%h' $VAR1 = [ 2, 3, 4, 5 ]; $VAR1 = { '1' => 3, '3' => 5 };

Replies are listed 'Best First'.
Re^2: Modifying hash keys via aliasing
by Discipulus (Canon) on Aug 11, 2015 at 09:41 UTC
    Your (and other's too) answer is correct and clear. But why no warnings are emitted in this case? like 'Redefine hash key not allowed at..' is similar to re-declare an already declared var, no?

    For the OP question, the desired output can also be achievied reassigning the entire hash, like:
    >perl -MData::Dumper -Mstrict -e 'sub t{ map {$_+=1 } @_}; my %h = (1 +=> 2, 3 => 4); %h = t(%h); print Dumper \%h' $VAR1 = { '4' => 5, '2' => 3 };


    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Yes, I agree, I also would have expected a warning (which is why I added the -w flag in the first place).

      Just as I would also have expected a warning saying something like "attempt to modify read-only value" with the following pieces of code:

      $ perl -Mstrict -wE 'say ++$_ for 1..4;' 2 3 4 5 ~ $ perl -Mstrict -wE 'say $_ for map {++$_} 1..4;' 2 3 4 5
      But there is no warning. On the other hand, you get a warning with this:
      $ perl -Mstrict -wE 'say $_ for map {++$_} (1, 2, 3, 4);' Modification of a read-only value attempted at -e line 1.
      There must be some reason, but it does not look very consistent to me.