syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I was looking at https://github.com/Perl/perl5/issues/22118 and, on perl-5.39.9 devel release, went looking for the difference between calling builtin::stringify() and scalar().
This somewhat simplistic little script failed to find any difference:
use strict; use warnings; use experimental qw(builtin); my @x = qw(one two three); my $_1st = builtin::stringify @x; my $_2nd = scalar @x; print $_1st, "\n", $_2nd, "\n\n"; $_1st = builtin::stringify "@x"; $_2nd = scalar "@x"; print $_1st, "\n", $_2nd, "\n\n"; print builtin::stringify @x, "\n"; print scalar @x, "\n\n"; print builtin::stringify "@x", "\n"; print scalar "@x", "\n\n"; # UPDATE: remove duplicate test #print builtin::stringify @x, "\n"; #print scalar @x, "\n\n";
Presumably, there are circumstances where builtin::stringify() and scalar() are not the same thing .... right ???

Cheers,
Rob

Replies are listed 'Best First'.
Re: Does the experimental builtin::stringify() do anything that scalar() doesn't ?
by choroba (Cardinal) on Apr 05, 2024 at 08:34 UTC
    #!/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]
      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]

        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

Re: Does the experimental builtin::stringify() do anything that scalar() doesn't ?
by syphilis (Archbishop) on Apr 05, 2024 at 08:28 UTC
    Presumably, there are circumstances where builtin::stringify() and scalar() are not the same thing ....

    I've finally found a difference, though I don't know if it's intended or accidental:
    D:\>perl -wle "print scalar(10,20);" Useless use of a constant (10) in void context at -e line 1. 20 D:\>perl -Mexperimental=builtin -wle "print builtin::stringify(10,20); +" Too many arguments for builtin::stringify at -e line 1, near "20)" Execution of -e aborted due to compilation errors.
    Cheers,
    Rob

      Well, the OP didn't really mean scalar, they meant "other means of forcing stringification", e.g. ''.$v.