3

Perl has a canonical "true" and "false" value which it uses for cases of Boolean negation with ! or not.

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper;

print Dumper !1;    # outputs $VAR1 = '';
print Dumper !!1;   # outputs $VAR1 = 1;

All good so far.

But, when I look at the values with Devel::Peek it is clear that they are not equivalent to literal '' and 1, they are both SV PVNV values.

$ perl -MDevel::Peek -E 'Dump ""; Dump !1;' 2>&1 | grep '^SV'
SV = PV(0x15e5140) at 0x1603298
SV = PVNV(0x15e3010) at 0x7814b0

$ perl -MDevel::Peek -E 'Dump 1; Dump !!1;' 2>&1 | grep '^SV'
SV = IV(0xfce228) at 0xfce238
SV = PVNV(0xfae030) at 0x7819f0

I have tested this with Perl 5.16.3 and Perl 5.20.0.

Isn't a PVNV much larger than a simple IV? Is this a case of Perl trading memory for speed?

Kaoru
  • 1,540
  • 11
  • 14

2 Answers2

5

Not just boolean negation; these values are returned by many builtins.

There is really no issue of memory, since there is only one instance of each of them.

The false value in particular must be a PVNV since its string value '' and its numeric value 0 are not derivable from each other (at least without triggering a warning).

ysth
  • 96,171
  • 6
  • 121
  • 214
  • 1
    Ah, so it's to allow you to do `0 + !1` and `"" . !1` without a warning for either case? Nice! Thanks. – Kaoru Jun 06 '14 at 07:00
1

I believe the answer here is that yes, a PVNV is larger, but Perl only keeps one copy of the true value and one copy of the false value in memory, so it's not like you're going to run out of memory having lots of Boolean values in your script.

I'm getting that from the reference count (REFCNT) from this Devel::Peek output:

$ perl -MDevel::Peek -E 'Dump !1; Dump !!1;'  2>&1 | grep REFCNT
  REFCNT = 2147483646
  REFCNT = 2147483644
Kaoru
  • 1,540
  • 11
  • 14