in reply to Does the experimental builtin::stringify() do anything that scalar() doesn't ?

#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use builtin qw{ stringify }; use Devel::Peek qw{ Dump }; my $v = 100; for (sub { scalar shift }, sub { stringify shift }) { $_->($v); Dump $v; }
Ouput:
Built-in function 'builtin::stringify' is experimental at 2.pl line 10 +. SV = IV(0xf57500) at 0xf57510 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 100 SV = PVIV(0xf20db0) at 0xf57510 REFCNT = 1 FLAGS = (IOK,pIOK,pPOK) IV = 100 PV = 0xf09d20 "100"\0 CUR = 3 LEN = 16

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: Does the experimental builtin::stringify() do anything that scalar() doesn't ?
by syphilis (Archbishop) on Apr 05, 2024 at 11:43 UTC
    Nice demo, choroba - thanks.
    So, unlike scalar(), builtin::stringify() fills the PV slot, and sets the pPOK flag. It also sets the CUR and LEN slots correctly.
    Given that it's called "stringify", I probably shouldn't be surprised by any of that ;-)
    First follow-up question is "Why is that useful ?".

    If, in your demo, $v is set to 100.5, then builtin::stringify() again correctly fills the PV, CUR and LEN slots, but the pPOK flag is NOT set.
    Is there any reason (apart from oversight) for that ?
    Does it matter ?

    Cheers,
    Rob
      > Why is that useful ?

      Some people probably find "" . $value too obscure to understand. stringify($value) fixes the problem.

      > Is there any reason (apart from oversight) for that ? Does it matter ?

      Interesting. I have no idea.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        >> Is there any reason (apart from oversight) for that ? Does it matter ?
        > Interesting. I have no idea.


        I doubt that it matters. In this instance bultin::stringify is doing the same thing to its argument as interpolation does:
        D:\>perl -MDevel::Peek -le "$x = 100; $y = \"$x\"; Dump $x;" SV = PVIV(0x1d14cb52750) at 0x1d14cb54110 REFCNT = 1 FLAGS = (IOK,pIOK,pPOK) IV = 100 PV = 0x1d14cb85630 "100"\0 CUR = 3 LEN = 16 D:\>perl -MDevel::Peek -le "$x = 100.5; $y = \"$x\"; Dump $x;" SV = PVNV(0x1ba09babdd8) at 0x1ba09be1070 REFCNT = 1 FLAGS = (NOK,pNOK) IV = 0 NV = 100.5 PV = 0x1ba09c47d00 "100.5"\0 CUR = 5 LEN = 48
        If there was a problem with that, then it would likely have already been encountered.
        (I actually have a vague and hazy recollection that this difference wrt the pPOK flag serves a purpose.)

        Thanks also to jdporter and davido for their helpful inputs.

        Cheers,
        Rob

      Why is that useful ?

      Data serialization. A string may serialize differently than an integer:

      { "foo":1, "bar":"2", }

      In the case of that little JSON blurb, a well behaved JSON emitter would take {foo => 1, bar => "2"} and emit JSON with two key/value pairs, one of which has an integer value, and the other of which has a string that contains the character '2'

      Why that matters is the subject of many hard to find little bugs


      Dave

        A best-behaved JSON emitter would require you to denote which elements are intended to be numbers, the same way it uses an object to let you denote which elements should be booleans. This would be in keeping with the design of perl, that a scalar should never have an implied type, and use typed operators to coerce the data as it gets used. It's only due to history and implementation details that our JSON modules have tried to be overly clever about detecting which scalars are meant to be numbers, and given us this headache.