This used not to work:
sub foo :lvalue { keys %wallet }
foo = 37;
Now it does. It was just a matter of following the right code path in
op_lvalue when the parent op is a leavesublv instead of a sassign.
case OP_KEYS:
case OP_RKEYS:
- if (type != OP_SASSIGN)
+ if (type != OP_SASSIGN && type != OP_LEAVESUBLV)
goto nomod;
goto lvalue_func;
case OP_SUBSTR:
/* FALL THROUGH */
case OP_POS:
case OP_VEC:
+ lvalue_func:
if (type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
- lvalue_func:
pad_free(o->op_targ);
o->op_targ = pad_alloc(o->op_type, SVs_PADMY);
assert(SvTYPE(PAD_SV(o->op_targ)) == SVt_NULL);
hashes being returned). Now a more general fix has been applied
[RT #23790].
+=item *
+
+Assignment to C<keys> returned from an lvalue sub used not to work, but now
+it does.
+
=back
=item *
@INC = '../lib';
require './test.pl';
}
-plan tests=>155;
+plan tests=>156;
sub a : lvalue { my $a = 34; ${\(bless \$a)} } # Return a temporary
sub b : lvalue { ${\shift} }
}
is("@p", "1 8");
+sub keeze : lvalue { keys %__ }
+%__ = ("a","b");
+keeze = 64;
+is scalar %__, '1/64', 'keys assignment through lvalue sub';
+
# Bug 20001223.002: split thought that the list had only one element
@ary = qw(4 5 6);
sub lval1 : lvalue { $ary[0]; }