Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

What are all the false values in Perl ((conditional, boolean, whitespace, unprintable characters)

by princepawn (Parson)
on Sep 22, 2000 at 19:16 UTC ( [id://33638]=perlquestion: print w/replies, xml ) Need Help??

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

The following simple subroutine:
sub log_msg { my $log_msg = shift; print "value $script::debug"; if ($script::debug) { print sprintf "(%s) $log_msg \n", shell_date; } }
still prints log messages when the printed value of $script::debug is 0.

So this yields two questions, and I would like an answer to both:

  • What are all the false values in Perl? I know of the following:
    1. "0"
    2. ""
    3. 0
    4. 0.0
  • How do one brute-force print every character in a string even if it is typically unprintable? That is, my guess is that things are being printed even when $script::debug appears to be zero when in fact there may be some hidden control char or something in the string.
    • Comment on What are all the false values in Perl ((conditional, boolean, whitespace, unprintable characters)
    • Download Code
  • Replies are listed 'Best First'.
    Re: What are all the false values in Perl ((conditional
    by swiftone (Curate) on Sep 22, 2000 at 19:36 UTC
      You forgot undef, which is also false.

      To check to see if there are characters in $script::debug that aren't printing you can always check the length of $string::debug.

      Update: Just thought of this: are you putting a \n in the variable? Because "0\n" is not "0".

    Re: What are all the false values in Perl ((conditional
    by Fastolfe (Vicar) on Sep 22, 2000 at 19:41 UTC
      I believe an empty string, the undefined value, an empty list/array and the number zero (numeric or "0") will return a false value. A non-empty string, an array with 1 or more elements, or a non-zero number will return a true value.

      If you're seeing a zero, be sure it's not a string with other characters besides a zero in it. I believe spaces or other characters before or after it may cause the variable to be evaluated as a numeric zero when you're doing math, but since there's more than a number in the string, a boolean test will look at it from a string point of view, and will return 'true' since it's a non-empty string.

      If $script::debug is being set to a numeric zero (or, better, undef), there's no reason the test you're describing should return a true value. I'd like to see how you're setting $script::debug.

      (Updated 'list' vs. 'array'.)

        Your list statement is incorrect:
        print "hello\n" unless (1, 0);
        Otherwise you are right. The false scalars are:
        undef, '', '0', 0.0;
        Truth is evaluated in void (essentially scalar) context so something that looks like a list (array, hash, etc) is coerced into a scalar before the boolean test.

        EDIT
        My bad for saying void when I meant Boolean.

        But note that when I said "looks like a list" I used that phrase very, very carefully. Many list-like things exist in Perl, but there is no list per se. For an earlier post of mine on this exact topic try Arrays are not lists.

        I would give an array slice example, but tye gave a better one than the one I was going to do... :-)

          That's not a list, that's the binary comma operator. Any non-empty list is true. It may look like a list, but it's not one.

          UPDATE:

          Hmm, "Any non-empty list is true" was a dumb thing to say, as tye and tilly pointed out.

          It reminds me of an MJD quote:

          "If there is a giant purple water buffalo returned from a function, then $h = func() will always give you the length of its nose."

          In other words, any non-empty list is true because you never have a list in boolean context.

          However, I do stand by my first and third sentences in the original post. I think it's misleading to say if (1,0) or even if @array[0,2,1] is a list.

          It is, obviously, a complicated topic.

        For an in-depth look at the topic of "list context", I point you to my PerlMonth.com article, "List" Is a Four-Letter Word.

        $_="goto+F.print+chop;\n=yhpaj";F1:eval
    RE: What are all the false values in Perl ((conditional, boolean, whitespace, unprintable characters)
    by aardvark (Pilgrim) on Sep 22, 2000 at 20:33 UTC
      There was a great article in The Perl Journal about this: What is Truth? - The Perl Journal, Summer 1999 http://www.itknowledge.com/tpj/issues/vol4_2/tpj04020002.html Good Luck
    Re: What are all the false values in Perl ((conditional
    by kilinrax (Deacon) on Sep 22, 2000 at 19:44 UTC
      If $script::debug == "\0", then it will appear empty, but evaluate as true.
      print "\Q$script::debug" would backslash all special characters, which would at least indicate their existence, though not their nature. TMTOWTDI, though there's probably a better way ;-)

      Update:

      my @unpack = unpack('C*', $script::debug); print "Unpack info: @unpack\n";
      Should give you the ascii codes of each character in $script::debug, which will hopefully be useful.

    Re: What are all the false values in Perl ((conditional
    by japhy (Canon) on Sep 22, 2000 at 19:46 UTC
      I agree with swift -- print length($string) if you're not sure... and as for printing "unprintables":
      sub literal { require 'dumpvar.pl'; &dumpValue; }
      The dumpvar.pl library is, in fact, what the debugger uses when you tell it x $string.

      $_="goto+F.print+chop;\n=yhpaj";F1:eval
        One can always make use of Data::Dumper if you would prefer modules to libraries.
          Yes, by setting $Data::Dumper::Useqq to 1.

          $_="goto+F.print+chop;\n=yhpaj";F1:eval
    Re: What are all the false values in Perl ((conditional
    by mrmick (Curate) on Sep 22, 2000 at 19:29 UTC
      I may be mistaken, but I think that once something is evaluated in scalar context, I believe it's context is set to 'TRUE'. You print statement has set it to true whether or not the value is true.

      Mick

    Log In?
    Username:
    Password:

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

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

      No recent polls found