Ruby has two sets of logical operators: &&
/||
and and
/or
. While they perform similar
operations, they have very different precedence levels that can lead to unexpected behavior.
The and
and or
operators have extremely low precedence - lower than assignment operators like =
. This means
they are evaluated last in most expressions, which often produces surprising results.
Consider this example:
result = condition1 and condition2
Due to precedence, this is actually parsed as:
(result = condition1) and condition2
This assigns condition1
to result
, then evaluates condition2
separately. The and
operation
doesn’t affect the assignment at all.
In contrast, &&
and ||
have higher precedence than assignment operators, so they work as most developers
expect:
result = condition1 && condition2
This correctly assigns the result of the logical operation to the variable.
The precedence issue becomes even more problematic in complex expressions with multiple operators, where the evaluation order can be completely
different from what appears obvious when reading the code.
What is the potential impact?
Using and
and or
can cause logic errors where variables receive unexpected values due to operator precedence. This can
lead to:
- Incorrect conditional logic that appears to work in simple cases but fails in complex expressions
- Variables being assigned partial results instead of the full logical operation
- Difficult-to-debug issues where the code looks correct but behaves unexpectedly
- Reduced code readability as other developers may misunderstand the actual execution order