Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

What is true and false in Perl?

by root (Scribe)
on Oct 29, 1999 at 03:24 UTC ( #862=perltutorial: print w/replies, xml ) Need Help??

Well for starters "0" and an empty string("") are false. Anything else is basically true.
0 # converts to "0" so it's false; "" # is empty string so it's false; "0.0" # not "0" or "" so it's true 0.0 # computes to 0 and is then converted to "0" so false undef # evaluates to "" so it's false -- note, you may get a warni +ng "use of uninitialized value" if you are using -w 2-3+1 # computes to 0 which is converted to "0" so it is false

Replies are listed 'Best First'.
Re: What is true and false in Perl?
by ambrus (Abbot) on Apr 07, 2005 at 19:30 UTC
    undef # evaluates to "" so it's false -- note, you may get a warni +ng "use of uninitialized value if you are using -w

    I belive you can not get such a warning, an undefined value is always false without any warning when interpreted as a boolean.

    From perlsyn, section Declarations (it's so well hidden):

    A variable holds the undefined value ("undef") until it has been assigned a defined value, which is anything other than "undef". When used as a number, "undef" is treated as 0; when used as a string, it is treated as the empty string, ""; and when used as a reference that isn't being of an uninitialized value whenever you treat "undef" as a string or a number. Well, usually. Boolean contexts, such as
    my $a; if ($a) {}
    are exempt from warnings (because they care about truth rather than definedness).
Re: What is true and false in Perl?
by bangers (Pilgrim) on Apr 16, 2009 at 15:21 UTC
    "0 but true" is (a bit) interesting:
    use strict; use warnings; print "0 but true" ? "true\n" : "false\n"; print "0 but true" + 0 ? "true\n" : "false\n"; print "0 but true" + 1 ? "true\n" : "false\n";
    No warnings using numeric addition on a string, despite the 'use warnings'. Also the second case is unexpected. Shouldn't 'True' + 1 be true?
      Why is the second case unexpected?

      "0 but true" is not "True".

      It means "treat me in numeric context as 0, but in boolean context as true".

      So when you do "0 but true" + 0 you are in numeric context, so you effectively do 0+0 which is 0 and this in turn (for the ? operator) is false.

      I find that quite logical (which probably shows that using Perl for too long causes brain-damage).

      And by the way: You are not doing numeric addition on a string, you are evaluating "0 but true" in numeric context (to 0) - therefore no warning.

        And by the way: You are not doing numeric addition on a string, you are evaluating "0 but true" in numeric context (to 0) - therefore no warning.

        That makes no sense. The correct answer is that "0 but true" is special-cased.

        $ perl -wle'print 0+"0 abc"' Argument "0 abc" isn't numeric in addition (+) at -e line 1. 0 $ perl -wle'print 0+"0 but true"' 0
Re: What is true and false in Perl?
by tobyink (Abbot) on Apr 16, 2012 at 16:37 UTC

    The oft-cited list of values considered false is:

    • undef
    • 0
    • ""
    • "0"
    • Any blessed objects that overload conversion to boolean to return false
    • Empty lists and empty hashes

    I did actually manage to find another value that Perl treats as false:


    You can see its interesting behaviour here:

    perl -E'say(-0.0 eq 0?"eq 0":"ne 0"); say(-0.0?"true":"false");' ne 0 false

    Note that it's false but not (stringy) equal to zero.

    This does vary between Perl versions. The behaviour documented above exists between Perl 5.6.x to 5.12.x (obviously you need to use print instead of say before Perl 5.10) and perhaps earlier. But in Perl 5.14.x, -0.0 is (stringy) equal to 0.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Another one that's false is a list of undefs. An array of undefs though is true.
      if ( (undef,undef) ) { } # a list of undefs is false @arr = (undef,undef); if ( @arr ) {} # an array of undefs is true
      We make use of this like so:
      $_ = 'x'; if (($a,$b) = m/(.)(.)/) { }

        That's not quite true. Observe:

        # Does not say "true". This is as you describe. say "true" if undef, undef; # Still doesn't say true. say "true" if 1, 2, 3, 4, undef;

        The reason for this behaviour is that if imposes a scalar context on the expression that acts as its condition. When the comma operator is used in a scalar context it is not a list constructor and instead evaluates the left argument, discards it and then evaluates the right argument (it basically acts like the semicolon but with a different precedence).

        Thus this:

        say "true" if 1, 2, 3, 4, undef;

        Is essentially the same as:

        sub x { 1; 2; 3; 4; return undef; } say "true" if x();
        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        It isn't a list nor an array in scalar context that your example is making use of. It is a list assignment (in scalar context).

        A list assignment in scalar context returns the number of items in the right-hand list.

        And, in your example, 'x' =~ m/(.)(.)/, in a list context, returns an empty list, not a list of two 'undef's. An empty list (on the right-hand side of the list assignment) contains zero items so the assignment in scalar context returns 0, which is one of the documented false values.

        But there is a kernel of truth hidden behind your mistakes.

        There have been some exceptions (as near as I can remember, on an inconsistent basis) to the rule about what a list assignment returns in scalar context. Those exceptions were meant to handle cases very similar to what you described.

        sub undefs { my( $count ) = @_; return ( undef ) x $count; } if( my( $x, $y ) = undefs(2) ) { print "true\n"; } else { print "false\n"; }

        In some versions of Perl, that code would print "false". In the relatively modern Perl I had handy, it prints "true".

        I even recall having a very short on-line conversation with Larry years ago about what I considered to be bugs such as ( undef, undef )[0] being an empty list instead of being a list containing a single 'undef' and he was worried about breaking the fact that the above code was supposed to print "false". I argued that that wasn't a feature worth keeping.

        But I didn't follow-up to see what decisions were made back then. And, just now, I didn't test the current behavior except minimally. I think there was at least one thread about this stuff on PerlMonks around the time Larry and I talked, but I haven't looked for it. It might've just been in the chatterbox.

        - tye        

        print "true" if "IS" eq "evaluates to in scalar context"; # doesn't pr +int.
Re: What is true and false in Perl?
by Anonymous Monk on Apr 15, 2009 at 14:58 UTC
    Could Perl possibly be more ridiculous? True and False are boolean values and should only ever exist as such. "0" is not boolean, and neither is "", nor in fact are any of the examples shown above. Providing such a 'feature' comes with a very significant readability and maintainability cost that is simply not justified.

      "0" is not boolean, and neither is "",

      Noone said they are. It was said they are false.

      Providing such a 'feature' comes with a very significant readability and maintainability cost that is simply not justified.

      That's odd. Perl, Python, PHP, C, C++, JavaScript, VB and the 5 or 6 CPU I know work that way. The only language I know that doesn't is Java.

        Also LISP.
      True and False are boolean values and should only ever exist as such.

      You and your silly two valued logic. Now go away or I shall taunt you a second time!

      I never said True and False were the only boolean values!

      Update: You didn't actually say that. But that's how you should have replied to this post, if I were to respect your opinion at all, not that you'd care whether or not I respect your opinion, nor do I care whether you care ...

      Really though, thank goodness we don't have to say if ( $is_foo == TRUE ) (although, sadly, some "programmers" still do...)

      I love this 'feature'. It allows code like the following:
      while (@array) { my $whatever = shift @array; # process $whatever; }
      The loop ends when the array is empty.
      Then don't use it.

      Add the following line to your program, then PERL will work as you prefer, grasshoppah.

      use constant { TRUE => 1, FALSE => 0 };

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perltutorial [id://862]
[Corion]: Also I found that I can't conveniently weaken an array slot, which also is inconvenient, as I want my one-shots to disappear if the caller discards them
[Corion]: choroba: Currently two or three that my program handles (WWW::Mechanize:: Chrome), but there might be more that become interesting
[Corion]: But I don't expect more than 100 to be active at the same time, so I'm not really sure if there is a not-too-fancy data structure that is maintained with few lines of code where the performance is better than the linear scan ;)
[Corion]: But I should do a mock-up program so that others can see what I'm talking about ;)
[robby_dobby]: Corion: I hope you know all too well that passing around "fancy" datastructures is a recipe for disaster :-)
[robby_dobby]: As in, it's-too-fancy- that-it-will-be- messy-to-handle
[choroba]: bit vectors as keys?
[robby_dobby]: Hmm, I keep falling asleep at my desk, while maintaining an active appearance. Am I getting old?
[robby_dobby]: Every time I fall asleep, there's a small guy in the dreams, shouting "Whoo!" and it jolts me awake. :/
[Lady_Aleena]: robby_dobby, at least you aren't driving. I seem to always be driving somewhere in my dreams and end up at a weird house.

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2017-05-29 08:01 GMT
Find Nodes?
    Voting Booth?