Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Truth and Falsehood

In Perl, the following values are false in boolean context:

  • The number zero (0)
  • The string "0"
  • The empty string ""
  • undef

All other values are true. (Two rare special cases are described below.)

Boolean context is a scalar context. Therefore the following things, when evaluated in boolean/scalar context, are also false:

  • An empty array, which evaluates to the number of elements it contains, i.e. zero (0).
  • An empty hash, which evaluates to a false value when it is empty.
  • The empty list (), which evaluates to undef.

A true value negated by ! or not, plus many of Perl's builtins/operators, return a special false value: When evaluated as a string it is treated as "", but as a number, it is treated as 0, without causing any warnings. (This is not the same as undef: even though undef is also "" as a string and 0 as a number, Perl's special false value is a defined value, and undef does produce warnings when you try to use it as a string or number. "" also causes warnings when you try to use it as a number.)

When the Perl documentation says that a operator or function returns "a false value" or "a true value" (or more simply, "false" or "true"), it may return any of the above values.

Related Topics

Context

Boolean context is provided by, for example, if (bool) { ... }, bool ? ... : ..., or statement if bool;. If you are unsure about Perl's concept of context, see e.g. the Context tutorial, the section "Context" in Chapter 2 of the Camel, or the section "Context" in Modern Perl.

Definedness

To test whether a value is undef or not, use defined. Note that "false" values like the empty string "" or the number 0 are still defined. Perl's special false value is defined as well.

Existence of Hash Keys

To test whether a hash contains a certain key or not, use exists. Note that a key can exist in a hash, but the value stored for that key can be undef. If you attempt to access a hash key that does not exist, Perl will also return undef, which is why the distinction between defined and exists is important, especially if you're going to be iterating over the keys of the hash. To remove a key from a hash, use delete.

String Length

To get the length of a string, use length. For example, the test if (length $string) allows you to differentiate between "0" and "", which would otherwise both be false. Note: As of Perl 5.12, if you give the length function an undef value, it will return undef without producing a warning, which is helpful in boolean tests. (In Perl versions before 5.12, length would produce a warning when given undef.)

Hash and Array Size

To get the size of an array, use scalar, as in scalar @array, or use the array in a scalar context, for example my $size = @array;. To test whether an array is empty or not, simply use it in a boolean context, such as if (@array). (Note: $#array returns the index of the last element of the array, so it is not the same - see perldata for details.)

If a hash is empty, using the hash in scalar/boolean context (e.g. if (%hash)) will return a false value, regardless of the Perl version. To portably get the number of keys in a hash, use keys in a scalar context, as in scalar keys %hash or my $size = keys %hash;. As of Perl 5.26, it is also possible to say scalar %hash directly to get the number of keys (previous versions of Perl would return some internal information about the hash: the number of used buckets and the number of allocated buckets).

Numerically Zero, But True

In a few special cases, Perl functions may wish to return the number zero, but want to do so in a way that this value is still "true" when tested in a boolean context. For example, this could be to indicate that an operation was successful, but its return value is zero. Two common ways to do this are for the function to return the strings "0E0" or "0 but true", which are both "true" under the above rules, but when used as a number, are zero. (The string "0 but true" is special-cased in Perl to not produce warnings about it not looking like a number.)

Forcing Boolean Context

To force some value into Perl's boolean values, you can use double negation, !!$value, also known as "bang bang" (perlsecret). If you're unsure about precedence, use parentheses: !!(...).

Special Case: Overloading

Normally, if ($object) would be true, since in the normal case a reference is a true value. However, an object may choose to change its behavior for different operations, such as boolean context. So, in the presence of overloading, if ($object) may be false. Authors of classes are generally advised to use this feature in a way that makes the code DWIM (Do What I Mean). (You may disable overloading with no overloading;, although in that form it will disable all overloading.)

Special Case: Dualvars

Perl has a special feature where a variable may contain two different values, one string and one number, that are different. In this case, the string part of the variable is tested for truth. For example, if you use Scalar::Util's dualvar to create a variable with a numeric part of 0 (false) and a string part of "1" (true), it will test true, and a variable with a numeric part 1 and a string part "0" is false. Note that this feature is rarely made use of intentionally, so you usually don't have to worry about it. To inspect a variable for this property, use Scalar::Util's isdual, and see Devel::Peek's output for all the gory details. (Thanks to tobyink for this suggestion!)

Edits: Minor clarifications. Added section on overloading, thanks Tux! Updates according to jcb's reply, thanks! 2019-12-30: Added section on forcing boolean context. 2020-10: A few tiny tweaks here and there, updated and added a few more links. 2021-02-23: Added a bit more to the section "Context" and a bit more about undef.

This node is to replace the "Truth and Falsehood" section that used to be in perlsyn, but was merged into a much longer text in perldata (and is now harder to link to explicitly, IMHO).


In reply to Truth and Falsehood by haukex

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-19 23:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found