Decisions
Choosing with if, elseif and else, comparing values, and the truth rule that only nil and false are false.
Only two things are false
Lua has a simple truth rule: every value is true except nil and false. Zero is true. An empty string is true. A table with nothing in it is true. This surprises people who come from languages where zero or an empty value counts as false.
So a test does not ask whether there is anything here unless you make it say so. if name then is true even when the name is an empty string.
Comparing values
The comparison signs are the ones you expect: == for equal, ~= for not equal, and the four order signs for less and greater. Note the not-equal sign in particular: it is a tilde and an equals, not an exclamation mark.
Two values are equal when they hold the same thing. 1 == 1.0 is true, because the two kinds of number compare by value, but a number is never equal to a string that looks like it.
if, elseif, else
An if runs a block when its condition is true. Add elseif for another test, and else for everything that is left. Each branch holds one or more lines, and end closes the whole thing.
Only the first branch whose condition is true runs, so order matters: put the most specific test first, and the catch-all last.
and and or choose a value
and and or do not only produce true or false; they hand back one of their operands. a or b gives a when a is truthy and b otherwise, which is why name or "guest" is a one-line default.
Both stop as soon as the answer is known. In ready and run(), run is not called when ready is false, and in name or build(), build is not called when a name exists. That short circuit is useful, and it is a trap when the right side does something you assumed had already happened.
Precedence, and what not returns
and binds tighter than or, and not tighter than either. a or b and c is a or (b and c), which is not the same as (a or b) and c. When the expression mixes the two, add brackets even if you are sure; the reader should not have to run the table in their head.
not always produces a boolean. not nil is true, not false is true, and not 0 is false because zero is truthy. That makes not the tool for turning any value into a clean yes or no, while and and or hand back one of their operands unchanged.
Comparing text and numbers
Numbers compare by value across the two kinds: 1 == 1.0 is true, and 2 < 2.5 is true. Text compares character by character, using the byte values, so "10" < "9" is true because the first character is the digit 1, which sorts before 9. That is correct for sorting identifiers and wrong for sorting numbers that happen to be stored as text.
A number and a string never compare equal, even when they look alike: "10" == 10 is false. Ordering across those types raises an error rather than guessing, so a value read from a file has to be converted with tonumber before it can take part in a numeric comparison.
How the branches are chosen
Lua tests conditions from top to bottom and runs the first block whose condition is truthy. Everything after it is skipped, including the later elseif tests, so the specific case goes first: an early broad test steals the branches below it.
A block made by if has its own scope. A local declared inside it disappears at end, so a value you need afterwards has to be declared before the if and assigned inside it.
A grade, and a truth check
local score = 72
if score >= 90 then
print("grade A")
elseif score >= 70 then
print("grade B")
else
print("grade C")
end
if 0 then
print("zero is true")
endThree traps worth knowing. else if is not elseif: two separate words start a new if, which needs its own end. A single = assigns, so if x = 1 is a syntax error rather than a comparison. And ordering a number against a string raises an error, while == across those types simply says false.
Try these next
- Write a ticket price that is free under 12, half price under 18, and full otherwise.
- Use
orto give a missing name a default, then test it with an empty string and see why the default does not fire. - Rewrite an
else ifaselseifand count theends before and after.
A grade, and a surprise
Run it and see which branch printed. Then change the score so a different branch wins, and add a test of your own that prints when a name is empty.
Ticket prices and a fallback
Run it and change the age so another branch wins. Then give `member` a name and watch the label change, and add a band of your own to the price list.
Because only nil and false are false, a test like if count then is true even when count is zero. When you mean greater than nothing, say so plainly with a comparison.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
Which values are false in Lua?
