Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Inchworm vs scalar: on boolean false value

by rsFalse (Chaplain)
on Dec 17, 2019 at 13:53 UTC ( [id://11110273]=perlquestion: print w/replies, xml ) Need Help??

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

Hello,

Today I've found for myself that inchworm "~~" (perlsecret operator: two consecutive unary inverse operators) gives '0' on "false", not ''. Can someone explain why behaviour of 'inchworm' and 'scalar' operators differ here?
#!/usr/bin/perl -l use strict; use warnings; map { print "[$_]" } scalar( 1 == 0 ), ~~ '', ~~ scalar( 1 == 0 ), ~~ ( 1 == 0 );
output:
[] [] [0] [0]
It is strange for me, that print ~~ scalar( 1 == 0 ) outputs '0' even when scalar( 1 == 0 ) corresponds to ''.

Replies are listed 'Best First'.
Re: Inchworm vs scalar: on boolean false value
by Eily (Monsignor) on Dec 17, 2019 at 14:20 UTC

    There are two things at work here. First, the false value of perl is actually neither strictly '' nor 0, it's kinda both (link to the doc when I find it). As demonstrated by

    perl -E "use strict; use warnings; say( '' + 1 ); say( !1 + 1 ); say ! +1; say '!1 is defined' if defined !1" Argument "" isn't numeric in addition (+) at -e line 1. 1 1 !1 is defined
    The warning about the non numeric argument happens only once, because !1 is treated as a number in arithmetic context. But printing !1 doesn't show anything because false is the empty string in string context.

    ~ however only works in two ways: bitwise not on a number, or bitwise not on a binary string. And the output will be of the same type. This means that ~~ is only equivalent to scalar when the operand is a number or a string, but it will force another type (probably string) on any other value (an object, a reference...).

    Edit: one place where the special value of perl's false is mentioned: Relational Operators.
    Also, ~~ is not equivalent to scalar for some big numbers and negative numbers:

    DB<1> say ~~ (-1) 18446744073709551615
    So it's better not to use it outside of obfuscated code.

      the false value of perl is actually neither strictly '' nor 0, it's kinda both (link to the doc when I find it).

      Truth and Falsehood :-)

Re: Inchworm vs scalar: on boolean false value
by LanX (Saint) on Dec 17, 2019 at 13:59 UTC
    ~ is a binary operation not a Boolean, IIRC.

    If you want Boolean results use !! instead.

    Update

    Uhm ... I think it might not do what you think it does.

    Binary "~~" does a smartmatch between its arguments.

    Better run B::Deparse to understand what the parser sees.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      Link to what he's using in perlsecret. Interestingly enough Deparse doesn't get much to work with (looks like the constant values generated are what's available; 5.26.1 using -MO=Deparse,-p,-q)

      BEGIN { $/ = "\n"; $\ = "\n"; } use strict; use warnings; map({print((('[' . $_) . ']'));} scalar((!1)), '', 0, 0);

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

      Binary "~~" does a smartmatch between its arguments.
      Here it's the unary ~~ though (or rather, two unary ~ in a row), because of the commas, the same way that A, -B is a list of two values, not the difference between the list (A,) and the scalar B.

        It looked unary for me too, but I'd rather prefer being sure.

        That's why I mentioned Deparse.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Inchworm vs scalar: on boolean false value
by Eily (Monsignor) on Dec 17, 2019 at 14:44 UTC

    Also, if you're not using the ouput of map, it's shorter and easier to read (IMHO at least) to use a postfix for loop:

    print "[$_]" for scalar( 1 == 0 ), ~~ '', ~~ scalar( 1 == 0 ), ~~ ( 1 == 0 );

Re: Inchworm vs scalar: on boolean false value
by LanX (Saint) on Dec 17, 2019 at 14:15 UTC
    Another thing to consider is IIRC that "false" or !!0 is a dual var which becomes 0 in numeric context and empty in string context.

    So is ~ now operating on the empty string or the 0?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11110273]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (8)
As of 2024-04-23 16:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found