On Thu, Jul 6, 2017 at 9:38 AM hw <h...@gc-24.de> wrote:

> Chas. Owens wrote:
> >
> >
> > On Sat, Jul 1, 2017, 12:44 Shlomi Fish <shlo...@shlomifish.org <mailto:
> shlo...@shlomifish.org>> wrote:
> >
> >     Hi Shawn!
> >
> >     On Sat, 1 Jul 2017 11:32:30 -0400
> >     Shawn H Corey <shawnhco...@gmail.com <mailto:shawnhco...@gmail.com>>
> wrote:
> >
> >     > !!$i which is !(!(0)) which is !(1) which is 0
> >     >
> >
> >     I suspect !1 returns an empty string in scalar context.
> >
> >
> > !1 returns PL_sv_no (an internal scalar variable). It is a dualvar that
> contains the empty string, the int 0 and the double 0.0. depending on the
> context the value is used in, it will be one of those values.
> >
> > Many people think it is an empty string because the print function
> forces string context.
> >
>
>
> perl -e 'my $i =0; $i = defined($i) ? (!!$i) : 0; use Data::Dumper; print
> Dumper($i);'
>
>
> A printing function should not force a context but use the context it is
> operating in.
>
> How do you print something without having a string context enforced upon
> you?
>

String context will always be force by printing (you don't print integers,
you print characters).  If you want to ensure that a dualvar uses the
double (or integer if the double doesn't exist), you use the venus secret
operator (so named because it looks like the Greek symbol for Venus  ♀):
0+.  Secret operators aren't really operators (or secret), but are just a
set of operators and arguments that are used idiomatically.

for example:

perl -E 'my $i = !!0; print "\$i as a string: [$i]\n\$i as an int: [",
0+$i, "]\n"'
$i as a string: []
$i as an int: [0]

Data::Dumper is not the best way to see what a variable holds if you care
about types. The Devel::Peek module gives you a much better picture, but
you do need to know a bit about perl (ie the interpreter) to understand it
(because Perl, the language, doesn't care about types):

perl -MDevel::Peek -E 'my $i = !!0; Dump $i'
SV = PVNV(0x7f88488036b0) at 0x7f884882a0b8
  REFCNT = 1
  FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
  IV = 0
  NV = 0
  PV = 0x7f8848405180 ""\0
  CUR = 0
  LEN = 10

Here we can see that $i is a PVNV, that is it holds a string (Pointer
Value) and a number (Number Value).  The flags IOK, NOK, and POK tell us
that the IV (integer), NV (double), and PV (string) portions are all safe
to use.

Now let's look at $i after the venus secret operator runs:

perl -MDevel::Peek -E 'my $i = 0+!!0; Dump $i'
SV = IV(0x7febe102a0a8) at 0x7febe102a0b8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 0

Now we can see that $i is an IV and it only has an IV section (and the
corresponding flag).

But be careful, you can taint this be using $i in a string context:

 perl -MDevel::Peek -E 'my $i = 0+!!0; "$i"; Dump $i'
SV = PVIV(0x7fd841004e20) at 0x7fd841002eb8
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 0
  PV = 0x7fd84070b3f0 "0"\0
  CUR = 1
  LEN = 10

>From this we can see that using an IV in string context will cause perl to
cache the string version of the IV.  But note that, unlike PL_sv_no, the
string value is actually "0" not "".  This is mostly an issue for
serialization (JSON in particular).

Just for illustration of why the flags are important:

perl -MDevel::Peek -E 'my $i = 0+!!0; Dump $i; "$i"; Dump $i; $i++; Dump $i'
SV = IV(0x7f941402a0a8) at 0x7f941402a0b8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 0
SV = PVIV(0x7f941402c020) at 0x7f941402a0b8
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 0
  PV = 0x7f9413c04eb0 "0"\0
  CUR = 1
  LEN = 10
SV = PVIV(0x7f941402c020) at 0x7f941402a0b8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
  PV = 0x7f9413c04eb0 "0"\0
  CUR = 1
  LEN = 10

$i started off as an IV, but gets promoted to a PVIV by being used in
string context.  Then math is done on the IV portion which invalidates the
cached string, so the POK flag is removed.  The cached value of "0" is
still present in the variable, but properly behaving code will not access
it (only XS code could even see it).

Just don't ask me about the pIOK, pNOK, and pPOK flags, 'cause I have never
understood what they represent.

Reply via email to