|Perl Monk, Perl Meditation|
Truth and Falsehoodby haukex (Chancellor)
|on Aug 17, 2019 at 09:19 UTC||Need Help??|
Truth and Falsehood
In Perl, the following values are false in boolean context:
All other values are true.
Boolean context is a scalar context. Therefore the following things, when evaluated in boolean/scalar context, are also false:
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.
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.
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.
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. To remove a key from a hash, use delete.
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. (Thanks to tobyink for this suggestion!)