Perl Part I · Module 2 · Variables, Scalars, and Data Types
Truth in Perl: What Counts as False
Perl's rule for truth is unusually short: four values are false and everything else is true. That brevity makes it easy to learn and hides one genuinely sharp edge. Because the list includes the string consisting of a single zero but not other ways of writing zero, the string 0.0 is true while the string 0 is false. Everything your scripts read from a file arrives as a string, which means two fields that both report a measurement of zero can land on opposite sides of the same test depending only on how the tool that wrote them chose to spell it.
Foundation12 min readPerlPart IFundamentalsTruthinessCorrectness
Part I · Module 2 · Chapter 2.8 · Truth in Perl: What Counts as False
1. Perl Has No Boolean Type
There is no separate true/false type in Perl, consistent with Chapter 2.6: a scalar has no type, so Perl decides truth by looking at the value it has.
The rule is short enough to memorise, and short lists are worth memorising exactly:
These four values are false:
undef, the empty string"", the number0, and the string"0". Every other value is true.
That is the whole rule. No exceptions beyond those four.
2. The List, Demonstrated
use strict;
use warnings;
print "undef is false\n" unless undef;
print "empty string is false\n" unless "";
print "number 0 is false\n" unless 0;
print "string 0 is false\n" unless "0";
print "string 0.0 is TRUE\n" if "0.0";
print "string 00 is TRUE\n" if "00";
print "string 0E0 is TRUE\n" if "0E0";
print "a single space is TRUE\n" if " ";undef is false
empty string is false
number 0 is false
string 0 is false
string 0.0 is TRUE
string 00 is TRUE
string 0E0 is TRUE
a single space is TRUEEvery line printed, which means every claim above is the measured behaviour. The second group is the surprising half:
"0.0"is true. It is not one of the four false values. It is a three-character string, and the rule does not say "any text that looks like zero"."00"is true, for exactly the same reason."0E0"is true, and is occasionally used deliberately as a value that is true but numerically zero." "is true. A single space is not the empty string.
3. Where the Edge Is
The strings above are true. The numbers written the same way are false:
use strict;
use warnings;
print "number 0.0 is false\n" unless 0.0;
print "number 00 is false\n" unless 00;number 0.0 is false
number 00 is falseSo the same characters mean different things depending on whether they are a number in your source or text in a variable:
| Value | Written as | True or false |
|---|---|---|
0 | number | false |
0.0 | number | false |
"0" | string | false |
"0.0" | string | true |
"00" | string | true |
"" | string | false |
Row three and row four are the whole problem. "0" is in the false list by name; "0.0" is not in the list at all, so it is true.
4. Why This Reaches Your Scripts
Now combine that with Chapter 2.5: everything read from a file, a log or a tool arrives as a string.
use strict;
use warnings;
my $field_a = "0"; # as a tool might write it
my $field_b = "0.0"; # as a different tool might write it
print "field_a is false\n" unless $field_a;
print "field_b is TRUE\n" if $field_b;field_a is false
field_b is TRUETwo fields. Both report zero. Both arrived as text. A truth test puts them on opposite sides — and nothing warns, because nothing is wrong as far as Perl is concerned.
Which one you get is not your decision. It depends on the tool, its version, and sometimes on which column of which report you happened to read. A script that asks if ($slack) to mean "is there a slack value" will behave differently against two tools that both reported the same measurement.
5. Where a Truth Test Is the Right Tool
This chapter should not leave you afraid of if. A truth test is exactly right when the value is one you created and whose meaning you control:
- A flag you set yourself to record that something happened.
- The result of a test that is genuinely about presence or absence of text, where empty means nothing was found.
- A counter you incremented, where zero genuinely means "none" — as long as you are sure it is a number you computed rather than text you read.
The distinction is about provenance. A value you computed has a shape you chose; a value you read has a shape someone else chose. Truth tests are safe on the first and risky on the second, and that is a more useful rule than trying to remember which strings are false.
6. Why This Matters in Engineering Work
The characteristic failure is a check that means "did this run report anything?" and is written as a truth test.
Take a script deciding whether a timing report contained a slack value. Written as if ($slack), it answers correctly for a missing field, correctly for most real values — and incorrectly for a slack of exactly zero, which it reports as missing. A slack of zero is a real and meaningful result: it means the path met its requirement with nothing to spare. Treating it as absent is wrong in the most consequential direction, because an absent value usually triggers an investigation and a zero does not.
Now add §4. If one tool writes that borderline value as 0 and another writes it as 0.0, the same script gives different verdicts on the same measurement. That is a bug that appears only when the toolchain changes, which is the hardest kind to find.
Both problems have one cause and one fix: ask the question you actually mean. defined for presence, a numeric comparison for zero. Part II's parsers are written that way throughout.
7. Common Mistakes
Assuming anything that looks like zero is false. "0.0" and "00" are true. Only the exact string "0" is in the false list.
Using a truth test for presence. if ($count) is false for a real zero. Chapter 2.7 covered this; it reappears here because truthiness is the mechanism behind it.
Forgetting that read values are strings. The whole of §4. A field arriving as "0.0" behaves differently from the number 0.0 you typed, and the difference is invisible on screen.
Treating " " as empty. A line that contains only a space is true. Code that checks for "nothing here" with a truth test will accept whitespace as content.
Expecting a warning. There is none. Perl has done nothing questionable — it applied its rule to the value it was given.
8. What You Should Be Able to Say Now
- Perl has no boolean type; truth is decided from the value.
- Exactly four values are false:
undef,"", the number0, and the string"0". Everything else is true. - The string
"0.0"is true; the number0.0is false. The spelling matters because the false list names one specific string. - Everything read from outside your script is a string, so which side of the rule a zero lands on is the tool's decision.
- A truth test is the wrong way to ask whether a value is present, or whether a number is zero.
- Truth tests are safe on values you computed and risky on values you read.
9. Exercise
Exercise 1 — reproduce the list. Write truth.pl from §2 and run it. Then add two lines of your own testing the strings "false" and "0 errors", predicting each before you run it.
Exercise 2 — explain the asymmetry. In two sentences, explain why "0.0" is true but 0.0 is false, referring to the four-item false list. Then say which of the two a script is more likely to encounter in practice, and why.
Exercise 3 — find the bug by prediction. This is meant to print slack is present and does not. Predict what it prints, run it, then explain the fault and say which test it should have used:
use strict;
use warnings;
my $slack = "0"; # read from a report: zero slack, met exactly
if ($slack) {
print "slack is present: $slack\n";
} else {
print "no slack value found\n";
}Exercise 4 — reason about a toolchain change. Your script uses if ($slack) and has worked for a year. The group upgrades a tool, and the same designs now report borderline paths as 0.0 instead of 0. Describe what changes in your script's behaviour, whether anything would warn you, and what the correct fix is.
10. Summary
- Four values are false:
undef,"", the number0, and the string"0". Everything else is true. - The string
"0.0"is true because the false list names one specific string, not every spelling of zero. - Read values are strings, so the tool that wrote your input decides which side of the rule a zero falls on.
- Nothing warns, because Perl applied its rule correctly to the value it received.
- Use
definedfor presence and a comparison for zero. A truth test answers a different question than either. - Trust truth tests on values you computed, not on values you read.
Chapter 2.9 takes the last of this module's big ideas — the one that explains more surprising Perl behaviour than any other — and asks what happens when Perl wants one value and you give it something that is not one.
Where this fits
Part of the Perl curriculum.
