http://www.perlmonks.org?node_id=886153

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

I was using ! operator today, and I notice a case where I expected a different output.

When I do !0, it results 1. But, when I do !1, it is neither returning 0 nor undef.

use 5.10.0; use strict; use warnings; my $r = !1; if (defined $r) { say "Defined"; } else { say "Not defined"; }

I don't understand, why it works this way. Help me to know what's happening in perl when I do this operation.

Replies are listed 'Best First'.
Re: how ! operator works
by davido (Cardinal) on Feb 04, 2011 at 08:14 UTC

    An empty string qualifies as "false" too. perlop tells us that ! provides logical negation, which is different from 'numeric.'

    perlsyn tells us the following:

    The number 0, the strings '0' and '' , the empty list () , and undef are all false in a boolean context. All other values are true. Negation of a true value by ! or not returns a special false value. When evaluated as a string it is treated as '' , but as a number, it is treated as 0.


    Dave

      This "False" value is basically the same as

      use Scalar::Util qw/dualvar/; dualvar(0, '');

      Which stems from the curious fact that a Perl scalar internally has a slot for both a numeric and a string value. By explicitly providing a numeric value, you don't get a warning when used as a number:

      $ perl -wE 'say 1 + ""' Argument "" isn't numeric in addition (+) at -e line 1. 1 $ perl -MScalar::Util=dualvar -wE 'say dualvar(0, "") + 1' 1

      Note that when abused, these dualvars can be very confusing:

      $ perl -MScalar::Util=dualvar -E 'my $x = dualvar(42, "23"); say $x; s +ay $x + 1' 23 43

      Devel::Peek shows that the False value is a wee bit more special than that:

      perl -MDevel::Peek -MScalar::Util=dualvar -e 'Dump !1; Dump dualvar(0, + "")' SV = PVNV(0x254ff70) at 0x7409c0 REFCNT = 2147483647 FLAGS = (IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x254ff50 ""\0 CUR = 0 LEN = 8 SV = PVNV(0x2550d90) at 0x2551220 REFCNT = 1 FLAGS = (TEMP,IOK,POK,pIOK,pPOK) IV = 0 NV = 0 PV = 0x255f610 ""\0 CUR = 0 LEN = 8

      So it's not only a dualvar, but it's also readonly, and has a very high refcount - it's basically a singleton.

        That refcount (2147483647) looks strangely familiar. Is that a coincidence or just a hack in the interpreter so it (the object in question) never gets destroyed by the garbage collector (theoretically)?
        ...what'd you just call me?
Re: how ! operator works
by ikegami (Patriarch) on Feb 04, 2011 at 08:44 UTC

    But, when I do !1, it is neither returning 0 nor undef.

    Those aren't the only false values. For example, an empty string is also false. It's not exactly an empty string being returned, though.

    It shouldn't matter to you at all what it returns as long as it's false, but the value it happens to return is zero in numeric contexts and the empty string in string contexts.

    >perl -wE"say ''.!1" >perl -wE"say 0+!1" 0

    If it was just zero, the result would be different:

    >perl -wE"say ''.0" 0 >perl -wE"say 0+0" 0

    If it was just the empty string, the result would be different:

    >perl -wE"say ''.''" >perl -wE"say 0+''" Argument "" isn't numeric in addition (+) at -e line 1. 0
Re: how ! operator works
by Fletch (Bishop) on Feb 04, 2011 at 15:39 UTC
Re: how ! operator works
by Deepthi (Initiate) on Feb 04, 2011 at 17:14 UTC
    You have assigned some value to $r variable. That's why it is showing as defined. If you give my $r; Then it will say not defined. Rest all cases, if you assign the variable any value, that means defined. my $r = !1; my $r = !0; my $r = "";