This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make lv keys distinguish scalar/list cx properly
keys(%h) was special in that it did not use the same code path as
other ops that distinguish between scalar and list lvalue context.
Consequently, some scalar lvalue contexts worked:
keys %h = 3;
${\scalar keys %h} = 3;
sub { $_[0] = 3 }->(scalar keys %h);
foreach(scalar keys %h) { $_ = 3 }
grep { $_ = 3 } scalar keys %h;
substr keys %h, 0, = 3;
while others did not:
keys %h .= 0;
read FH, keys %h, 0;
Fixing other bugs in the same code paths without breaking keys (or
adding *more* exceptions) is harder to do if keys is not consistent.
So this commit allows .= and read to assign to keys, by using the same
internal code (scalar_mod_type) that determines whether %h assignment
is allowed. The logic is reversed (since %h is list-only and keys %h
is scalar-only), so where %h is a valid lvalue keys %h is not, and
vice versa.