This statement mimics a ternary operator in the Lua programing language:
local result = condition and true_value or false_value
But how does it work? Why does it give true_value
if the condition is true?
how does it work? Why does it give true_value if the condition is true?
Lua has a few concepts that are necessary to understand to give a complete answer here.
It's first important to understand how and
and or
work - which may seem obvious but for completeness, from the official docs:
The operator
and
returns its first argument if it is false; otherwise, it returns its second argument
And also:
The operator
or
returns its first argument if it is not false; otherwise, it returns its second argument
Also from the docs, operator precedence:
and
has a higher precedence thanor
That means that this code from the question:
local result = condition and true_value or false_value
Can be read as:
local result = (condition and true_value) or false_value
These two code examples are functionally identical.
If you're new to lua, booleans can be surprising.
false and nil as false and anything else as true
Why do I point this out? because the concept of truthiness is quite different in lua, all of these evaluate to true:
{}
Let's look at a few scenarios to drill things home.
condition
is True> condition=true
> true_value="true value"
> false_value="false value"
> result = (condition and true_value) or false_value
> result
true value
In this case:
and
is not false
or nil
and
is evaluated
false
or nil
, so it is returnedor
is not false
or nil
false_value
is not evaluatedcondition
is False> condition=false
> true_value="true value"
> false_value="false value"
> result = (condition and true_value) or false_value
> result
false value
In this case:
and
is false
and
is not evaluatedor
is false
false_value
is evaluated and returnedThere are many scenarios that can trip folks up unfamiliar with lua.
condition
is truthyIf condition is not a boolean, it's going to be cast to a boolean to evaluate the and
. so e.g.:
> condition=0
> true_value="true value"
> false_value="false value"
> result = (condition and true_value) or false_value
> result
true value
In this case:
and
is not false
or nil
true
and
is evaluated
false
or nil
, so it is returnedor
is not false
or nil
false_value
is not evaluatedIn many other languages you may expect to get false_value
here, but not with Lua.
true_value
is falseIf true_value
is false
or nil
this is the typical scenario that trips folks up:
> condition=true
> true_value=false
> false_value="false value"
> result = (condition and true_value) or false_value
> result
false value
In this case:
and
is not false
or nil
and
is evaluated
false
(condition and true_value)
is therefore false
or
is false
false_value
is evaluated and returnedThis can be particularly confusing if there are functions in use, here's a fabricated example:
> user_provided_valid_input=true
> result = (user_provided_valid_input and doThing()) or tell_user_their_input_was_bad()
If doThing
returns nil
(e.g. doesn't have a return value) or false
(e.g. encounters an error) then tell_user_their_input_was_bad()
will be called.
The code in the question is equivalent to:
intermediate = condition and true_value
result = intermediate or false_value
a and b or c
unless you fully understand the possible pitfalls