diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-01-17 22:51:32 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-01-17 22:51:32 -0800 |
commit | 5ee80e13ad1338a061ce31e1c7ea5c074fc5a0ff (patch) | |
tree | a147ea2cd65e3149b6168e8193cbd3448acc7b23 /pp.c | |
parent | 485495c37ef9e4aac088b1f65dff57b9b274003c (diff) | |
download | perl-5ee80e13ad1338a061ce31e1c7ea5c074fc5a0ff.tar.gz |
[perl #108480] $cow |= number undefines $cow
If a read-only scalar is passed to one of | & ^ and it decides to do
a numeric operation, the numeric flags on the read-only scalar are
turned off afterwards if they were not on to begin with.
This was introduced in commit b20c4ee1f, which did so to stop $x | "0"
from coercing the rhs and making it behave differently the second
time through.
What that commit did not take into account was that the read-only
flag is set on cow scalars, and the same pp function is used for the
assignment forms. So it was turning off the numeric flags after
$cow |= 1, leaving $cow undef.
I made this numeric flag-twiddling apply only to read-only scalars
(supposedly), because that seemed the most conservative and acceptable
change. I am actually in favour of extending it to all scalars, to
make these operators less surprising. For that reason, this commit
preserves the current behaviour with cows in the non-assignment case:
they don’t get coerced into numbers. Changing them to work the same
way as non-cow writable scalars would make things more consistent, but
more consistently buggy. I would like to make this non-coercion apply
to all scalars in 5.18.
This commit simply skips the flag-twiddling on the lhs in the assign-
ment case.
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 4 |
1 files changed, 2 insertions, 2 deletions
@@ -2193,7 +2193,7 @@ PP(pp_bit_and) const UV u = SvUV_nomg(left) & SvUV_nomg(right); SETu(u); } - if (left_ro_nonnum) SvNIOK_off(left); + if (left_ro_nonnum && left != TARG) SvNIOK_off(left); if (right_ro_nonnum) SvNIOK_off(right); } else { @@ -2227,7 +2227,7 @@ PP(pp_bit_or) const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r); SETu(result); } - if (left_ro_nonnum) SvNIOK_off(left); + if (left_ro_nonnum && left != TARG) SvNIOK_off(left); if (right_ro_nonnum) SvNIOK_off(right); } else { |