Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: What is the correct definition of False and Null in Perl?

by davido (Cardinal)
on Oct 07, 2011 at 22:38 UTC ( [id://930255]=note: print w/replies, xml ) Need Help??


in reply to What is the correct definition of False and Null in Perl?

Maybe just a long day. Here are four good explanations from trusted sources.

But how does Perl decide whether a given value is true or false? Perl doesn’t have a separate Boolean datatype, like some languages have. Instead, it uses a few simple rules:

  • If the value is a number, 0 means false; all other numbers mean true.
  • Otherwise, if the value is a string, the empty string ('') means false; all other strings mean true.
  • Otherwise (that is, if the value is another kind of scalar than a number or a string), convert it to a number or a string and try again.

There’s one trick hidden in those rules. Because the string '0' is the exact same scalar value as the number 0, Perl has to treat them both the same. That means that the string '0' is the only non-empty string that is false.

Randal L. Schwartz; brian d foy; Tom Phoenix. Learning Perl, 6th Edition (Kindle Locations 1895-1904). O'Reilly Media.

And...

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.

perlsyn, Truth and Falsehood

And of course there's the Camel book you referred to:

Truth in Perl is always evaluated in a scalar context. Other than that, no type coercion is done. So here are the rules for the various kinds of values a scalar can hold:

  1. Any string is true except for "" and "0".
  2. Any number is true except for 0.
  3. Any reference is true.
  4. Any undefined value is false.

Larry Wall; Tom Christiansen; Jon Orwant. Programming Perl, 3rd Edition (Kindle Locations 1991-1995). O'Reilly Media.

The Perl Cookbook delivers a brief explanation as to "why."

Two defined strings are false: the empty string ("") and a string of length one containing the digit zero ("0"). All other defined values (e.g., "false", 15, and \$x) are true. You might be surprised to learn that "0" is false, but this is due to Perl's on-demand conversion between strings and numbers. The values 0., 0.00, and 0.0000000 are all numbers and are therefore false when unquoted, since the number zero in any of its guises is always false. However, those three values ("0.", "0.00", and "0.0000000") are true when used as literal quoted strings in your program code or when they're read from the command line, an environment variable, or an input file.

This is seldom an issue, since conversion is automatic when the value is used numerically. If it has never been used numerically, though, and you just test whether it's true or false, you might get an unexpected answer—Boolean tests never force any sort of conversion. Adding 0 to the variable makes Perl explicitly convert the string to a number:

Tom Christiansen; Nathan Torkington. Perl Cookbook, 2nd Edition (Kindle Locations 2815-2825). O'Reilly Media.

I bolded the most important part of that last excerpt.


Dave

Replies are listed 'Best First'.
Re^2: What is the correct definition of False and Null in Perl?
by Marshall (Canon) on Oct 08, 2011 at 15:42 UTC
    There are some special case true/false situations!

    (1) In Perl, the string: "0 but true" is an exception. This string will evaluate to a numeric 0, but a logical true! The logical "true" is not surprising, but the numeric 0 is! That is because this is a special case coded into Perl. Even under use strict; use warnings;, "0 but true" can be used in a numeric expression/computation.

    #!/usr/bin/perl -w use strict; my $x = "0 but true"; print $x + 1; #prints 1!!! my $xx = "1 but true"; # print $xx +1; #Ooops ERROR! #non-numeric addition!
    (2) There is a more "modern way" of returning the "0 but true" value. That is the string "0E0". The DBI will return this to mean: "hey, I worked!, but I modified zero rows". 10**0 is one. So 0*10**0=0*1=0. So this enables the conveyance of (a)I worked (no error) and (b)result is zero within a single string value "0E0".

    I have not seen recent code with the case (1) above. But I have verified that it does indeed work. You don't have to get too far into the DBI before you encounter (2) like when you are updating a table - the table update was just fine "true", but it just didn't do anything (rows modified = 0).

      > That is because this is a special case coded into Perl.

      every string starting with a number (plus leading whitespaces) evaluates to that number.

      The only specialty about "0 but true" are the missing messages under "warnings".

      DB<102> $a=" 41 The ultimate answer!" DB<103> print ++$a 42

      I would rather prefer "0.0" or "0E0", if I was calling functions in scalar context.

      Cheers Rolf

        The only specialty about "0 but true" are the missing messages under "warnings".

        Yes. That is correct. "0 but true" is a special case that does not emit a warning when used in a numeric expression.

        0E0 is the "standard way" of "true but zero".

        0.0 is not quite the same as 0E0. The DBI uses 0E0. Ok, maybe 0.0 could have been used, but it wasn't. I think that it is pointless to debate 0E0 vs 0.0, 0E0 has won and so let's go to another question.

Re^2: What is the correct definition of False and Null in Perl?
by flexvault (Monsignor) on Oct 08, 2011 at 11:17 UTC

    Your reference to the "The Perl Cookbook" was what I needed. I checked my copy and on page two is the definition, and I even had the phrase highlighted.

    "Two defined strings are false: the empty string ("") and a string of length one containing the digit zero ("0")."

    Thank you

    "Well done is better than well said." - Benjamin Franklin

Re^2: What is the correct definition of False and Null in Perl? [non-decimal strings]
by LanX (Saint) on Oct 08, 2011 at 12:05 UTC
    > Adding 0 to the variable makes Perl explicitly convert the string to a number:

    However there is still confusion with some number formats like hexadecimal, because Perl only converts strings which represent integers or floats as decimals! (see perlnumber).

    just run

    $a="0x10"; ++$a;

    and in Perl $a is now 1 in JS it's 17!

    Cheers Rolf

    UPDATE: OTOH JS obviously can't handle octals the same way:

    repl> $a=010; ++$a 9 repl> $a="010"; ++$a 11

      I redid your code, dropping the quotes as:

      $a=0x10; ++$a; print "$a\n";

      And the result was 17 (perl5.10.1 and perl5.12.2), which I think was what you wanted.

      P.S. I am amazed how many good comments have come from this question and the PM answers.

      Thank you

      "Well done is better than well said." - Benjamin Franklin

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://930255]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2024-04-23 13:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found