The key should be stored before the value is calculated. Left to order evaluation of block members (i.e. a list), i.e. copy away GvSV(defgv).
perl -e'sub x{$_="ouch"};%h=map{$_=>x}(0..3);print join" ",%h' => (ouch=>ouch), but should be
(1=>ouch, 2=>ouch, 0=>ouch, 3=>ouch), because the map list is (ouch, ouch, ouch, ouch, ouch, ouch), which is then collapsed to (ouch=>ouch).
Same problem with sub x{$_="ouch"};@h=map{$_=>x}(0..2);print join ", ",@h => (ouch, ouch, ouch, ouch, ouch, ouch) which should be (0, ouch, 1, ouch, 2, ouch) instead.
$_=>x => x changes $_, but should not influence the former key/list result.
See PatrickCronin/Map-Functional#1
Looks like the problem cannot be solved at runtime.
mapstart sets a fresh $_, then the block produces the stack entries, then mapwhile consumes them.
The problem happens in the block, which overwrites $_ before mapwhile can consume them.
The compiler could be changed to split the block into static list entries with interspersed mapwhile
consumers.
mapstart { stmt, stmt } mapwhile =>
mapstart { stmt; mapwhile; stmt } mapwhile
This would help for the obvious static lists {$_=>$v} and {$_=>x}, but not for the 2nd problem with the call producing a list {x}. Which is fine.
For hash assignments we could restrict the mapwhile producer to accept only pairs, not arbitrary lists. Something like use strict 'hashpairs'. See #281