248

I have tried:

$var = false;
$var = FALSE;
$var = False;

None of these work. I get the error message

Bareword "false" not allowed while "strict subs" is in use.
2
  • 42
    You might want to start with my book Learning Perl. It's easier than guessing what to do until you get it right (monkeys, typewriters, and Hamlet, and all that). :) Commented Jun 24, 2009 at 17:30
  • 1
    Over a decade later, Perl gets true and false "distinguished booleans" through the new builtin package Commented Nov 2, 2023 at 16:46

10 Answers 10

309

Truth and Falsehood in man perlsyn explains:

The number 0, the strings '0' and "", the empty list "()", and "undef" are all false in a boolean context. All other values are true.

In Perl, the following evaluate to false in conditionals:

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

The rest are true. There are no barewords for true or false. (Note: Perl v5.38 introduced true and false through the new builtin pragma).

Sign up to request clarification or add additional context in comments.

19 Comments

@BlueWaldo: you can also use cmp and <=> when comparing and assigning the results of the comparison to a scalar. $var = $var1 cmp $var2; 'cmp' and '<=>' (used for numeric comparisons) returns -1, 0, or 1 if left argument is less than, equal to, or greater than the right argument. Its not boolean but sometimes you may want to know if one argument ir equal or less than or greater than the other instead of just equal or not equal.
Problem 1: An empty list is not false, since it's impossible to check if an list is true or false. An empty list in scalar context returns undef.
Problem 2: ('') and '' are the same value. I think you wanted to imply a list with an element that consists of an empty string (even though parens don't create lists), but as I've already mentioned, it's impossible to check if a list is true of false.
Problem 3: Objects with an overloaded boolean operator can also be false.
@eternicode, Perl does have two specific value it uses when it needs to return true and false, so not only does it have booleans, it has true (!0 aka PL_sv_yes) and false (!1 aka PL_sv_no). Or are you saying Perl should croak whenever something other than these two values are tested for truthness? That would be completely awful. e.g. It would prevent $x ||= $default;
|
77

Since 5.36, you can use true and false from the builtin module/namespace. These are special true and false values that can be identified using is_bool. This is an experimental feature at this time.

But while these could be said to return the true and false, they are are but a true or false value respectively. In fact, every scalar is either true or false.

The most complete, concise definition of a false value I've come across is:

Anything that stringifies to the empty string or the string 0 is false. Everything else is true.

Therefore, the following values are false:

  • The empty string.
  • The string 0.
  • A signed integer with value zero.
  • An unsigned integer with value zero.
  • A floating point number with value positive zero.
  • A floating point number with value negative zero.
  • An undefined value.
  • An object with an overloaded boolean operator that evaluates one of the above.
  • A magical variable that evaluates to one of the above on fetch.

Any other scalar is true.


A note on "true zeroes"

While numbers that stringify to 0 are false, strings that numify to zero aren't necessarily. The only false strings are 0 and the empty string. Any other string, even if it numifies to zero, is true.

The following are strings that are true as a boolean and zero as a number:

  • Without a warning:
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • With a warning:
    • Any string for which Scalar::Util::looks_like_number returns false. (e.g. "abc")

9 Comments

if I understood you right the word true in While numbers that stringify to 0 are true should be false or (to prevent confusion) evaluate to false.
Your "concise" definition is inconsistent with your longer explanation. Consider: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Now $value will stringify to "XXX" but boolifies to false.
@tobyink, The concise version isn't perfect, merely the best I've found. It's meant to be practical, not all-encompassing. Do note that value returned by your bool does stringify to 0. Also, you are discouraged from creating inconsistent overloads, and the values you return could be considered such. (e.g. a && can be optimized into a ||, so if these were inconsistent, you'd have a problem.)
I'm not sure if 0x00 is covered here.
@Grinn, A list assignment in scalar context evaluates to the number of scalars to which its RHS evaluates. (See Scalar vs List Assignment Operator for details.) If the sub returns nothing, the assignment will evaluate to 0, which is false. If the sub returns at least one scalar, the assignment will evaluate to a positive number, which is true.
|
63

Perl doesn't have a native boolean type, but you can use comparison of integers or strings in order to get the same behavior. Alan's example is a nice way of doing that using comparison of integers. Here's an example

my $boolean = 0;
if ( $boolean ) {
    print "$boolean evaluates to true\n";
} else {
    print "$boolean evaluates to false\n";
}

One thing that I've done in some of my programs is added the same behavior using a constant:

#!/usr/bin/perl

use strict;
use warnings;

use constant false => 0;
use constant true  => 1;

my $val1 = true;
my $val2 = false;

print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

The lines marked in "use constant" define a constant named true that always evaluates to 1, and a constant named false that always evaluates by 0. Because of the way that constants are defined in Perl, the following lines of code fails as well:

true = 0;
true = false;

The error message should say something like "Can't modify constant in scalar assignment."

I saw that in one of the comments you asked about comparing strings. You should know that because Perl combines strings and numeric types in scalar variables, you have different syntax for comparing strings and numbers:

my $var1 = "5.0";
my $var2 = "5";

print "using operator eq\n";
if ( $var1 eq $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

print "using operator ==\n";
if ( $var1 == $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

The difference between these operators is a very common source of confusion in Perl.

3 Comments

use warnings; instead of #! perl -w
Using constants as a poor mans macros that way is dangerous. These code examples aren't equivalent: if ($exitstatus) { exit; } vs if ($exitstatus == true) { exit; }, which might not be obvious to a casual observer. (And yes, the last example is poor programming style, but that is beside the point).
Indeed, constants don't just name general values. You'd want something like use constant EX_SUCCESS => 0. Now you don't care if that is true or false as long as it matches in $exit_status == EX_SUCCESS.
16

I recommend use boolean;. You have to install the boolean module from CPAN though.

2 Comments

In Perl, as in life, there are many truths. The inexperienced like to write silly things like if ($my_true_value == true). Pretending that there is One True Truth is, in my experience, a path to pain, and inefficient code.
Perl is philosophical by nature
15

My favourites have always been

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

which is completely independent from the internal representation.

3 Comments

Brilliant. You single-handedly fixed the Perl programming language!
You think this works until something else produces a different value. Something like $var eq TRUE or $var == TRUE will now fail for almost all true values except for two of them. Conversely, the FALSE will work for almost all values except a couple of them. Then you are left with something like ($var eq $foo) == TRUE or !! $var == TRUE, but those are just silly.
Could you be more concise about something else produces a different value? In their scope, the constants are comparable to any logical expression or result thereof, in contrast to using self-defined values like in James' answer above.
9

I came across a tutorial which have a well explaination about What values are true and false in Perl. It state that:

Following scalar values are considered false:

  • undef - the undefined value
  • 0 the number 0, even if you write it as 000 or 0.0
  • '' the empty string.
  • '0' the string that contains a single 0 digit.

All other scalar values, including the following are true:

  • 1 any non-0 number
  • ' ' the string with a space in it
  • '00' two or more 0 characters in a string
  • "0\n" a 0 followed by a newline
  • 'true'
  • 'false' yes, even the string 'false' evaluates to true.

There is another good tutorial which explain about Perl true and false.

1 Comment

This is what perldata says. Always try to get back to fundamental sources. It's a real disservice when tutorials don't give you the source of the information.
6

Beautiful explanation given by bobf for Boolean values : True or False? A Quick Reference Guide

Truth tests for different values

                       Result of the expression when $var is:

Expression          | 1      | '0.0'  | a string | 0     | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var )          | true   | true   | true     | false | false     | false
if( defined $var )  | true   | true   | true     | true  | true      | false
if( $var eq '' )    | false  | false  | false    | false | true      | true
if( $var == 0 )     | false  | true   | true     | true  | true      | true

2 Comments

Poor answer, but a strong, reputable source in perlmonks.org. It would be nice to have some real content instead of a comment and a link. :-/
Note that this table has some errors. Testing a string in if( $var ) doesn't mean true for all strings. The empty string and the string of exactly 0 are false. Likewise, in the other rows, you have to know what is in $var for the "a string" column,. The last three rows are operators that return true or false, so their rows aren't that interesting.
2

Perl v5.38 introduced experimental "distinguished booleans" through the new builtin pragma. This means that you now have the true or false that you wanted.

use v5.38;
use experimental qw(builtin);
use builtin qw(true false);

my $var = false;

Comments

1

use the following file prefix, this will add to your perl script eTRUE and eFALSE, it will actually be REAL(!) true and false (just like java)

#!/usr/bin/perl
use strict;
use warnings;

use constant { #real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
                eTRUE  =>  bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
                eFALSE =>  bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
             };

There are, actually, few reasons why you should use that.

My reason is that working with JSON, I've got 0 and 1 as values to keys, but this hack will make sure correct values are kept along your script.

Comments

-3

Booleans in Raku (the programming language formerly known as Perl_6):

~$ raku
Welcome to 𝐑𝐚𝐤𝐮𝐝𝐨™ v2021.06.
Implementing the 𝐑𝐚𝐤𝐮™ programming language v6.d.
Built on MoarVM version 2021.06.

To exit type 'exit' or '^D'

> my $var = False;
False
> say $var;
False

> say $var.^name
Bool
> say $var.WHAT
(Bool)

> say ++$var
True
> say --$var
False

> say $var.Int
0
> say $var.Int + 1
1
> say ($var.Int + 1).Bool
True
> say $var.Int - 1
-1
> say ($var.Int - 1).Bool
True

> say $var.succ
True
> say $var.Int.succ
1
> say $var.pred
False
> say $var.Int.pred
-1

> say ++($var.Int); #ERROR
Cannot resolve caller prefix:<++>(Int:D); the following candidates
match the type but require mutable arguments:
    (Mu:D $a is rw)
    (Int:D $a is rw --> Int:D)
    #<SNIP>    
> say --($var.Int); #ERROR
Cannot resolve caller prefix:<-->(Int:D); the following candidates
match the type but require mutable arguments:
    (Mu:D $a is rw)
    (Int:D $a is rw --> Int:D)
    #<SNIP>

> exit

https://docs.raku.org/type/Bool
https://docs.raku.org/language/syntax#index-entry-Boolean_(literals)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.