This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #118159] Make PVs take precedence in SvTRUE
authorFather Chrysostomos <sprout@cpan.org>
Sun, 26 May 2013 06:59:45 +0000 (23:59 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 26 May 2013 07:18:23 +0000 (00:18 -0700)
Commit 4bac9ae4 (probably inadvertently) changed SvTRUE to treat an SV
with any of PVX, IVX or NVX having a true value as true.

Traditionally, truth was based solely on stringification. The examina-
tion of the SvIVX and SvNVX slots was for those cases where there was
no string already and it could be deduced from IVX or NVX whether it
would stringify as "0" or no (bugs with -0 aside).

This changes things back to the way they have ‘always’ been.

sv.h
t/op/not.t

diff --git a/sv.h b/sv.h
index 98aef7a..449b23e 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1738,9 +1738,10 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>.
 #define SvTRUE_common(sv,fallback) (                   \
       !SvOK(sv)                                                \
        ? 0                                             \
-    : (SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK))                \
-       ? (   (SvPOK(sv) && SvPVXtrue(sv))              \
-          || (SvIOK(sv) && SvIVX(sv) != 0)             \
+    : SvPOK(sv)                                                \
+       ? SvPVXtrue(sv)                                 \
+    : (SvFLAGS(sv) & (SVf_IOK|SVf_NOK))                        \
+       ? (   (SvIOK(sv) && SvIVX(sv) != 0)             \
           || (SvNOK(sv) && SvNVX(sv) != 0.0))          \
     : (fallback))
 
index 4aae02c..8df5774 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 16;
+plan tests => 19;
 
 # not() tests
 pass("logical negation of empty list") if not();
@@ -62,3 +62,17 @@ is(! (0, 0), not(0, 0),
     ok($not0 == 1,
         "logical negation (low-precedence) of false value is true in numeric context");
 }
+
+# test truth of dualvars
+SKIP:
+{
+    my $got_dualvar;
+    eval 'use Scalar::Util "dualvar"; $got_dualvar++';
+    skip "No Scalar::Util::dualvar", 3 unless $got_dualvar;
+    my $a = Scalar::Util::dualvar(3, "");
+    is not($a), 1, 'not(dualvar) ignores int when string is false';
+    my $b = Scalar::Util::dualvar(3.3,"");
+    is not($b), 1, 'not(dualvar) ignores float when string is false';
+    my $c = Scalar::Util::dualvar(0,"1");
+    is not($c), "", 'not(dualvar) ignores false int when string is true';
+}