jd77 - 1 year ago 134
Ruby Question

# Logical OR order of operations/precedence not as expected

The binary "or" operator will return the logical disjunction of its
two operands. It is the same as "||" but with a lower precedence

As I understand it, as || has a higher precedence than "or", the code below will first test if 'b' is true, then 'c', and then if both are false will test 'a'. I would like to witness this but am not sure if my understanding is incorrect, or simply my test.

``````a = true
b = false
c = false
p a or b || c
==> true #but were b and c checked as expected?
``````

My attempt to test this is as follows..

``````def atest
a = "string a"
a.include? 'string'
a
end

def btest
b = "string b"
b.include? 'string'
b
end

def ctest
c = "string c"
c.include? 'string'
c
end

puts "#{atest or btest || ctest}"
==> string a
``````

I expected 'string b' to be returned... I'm completely new to programming since a week ago so I'm not sure, is my code wrong or is my understanding of the quote wrong?

In Ruby, `&&`, `and`, `||`, and `or` are short-circuit operators:

[...] the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the `AND` function evaluates to `false`, the overall value must be `false`; and when the first argument of the `OR` function evaluates to `true`, the overall value must be `true`.

``````a or b || c
``````

Ruby evaluates `a`, sees a truthy value and immediately returns it, without evaluating `b || c`.

`or`'s lower precedence means that the expression is evaluated as:

``````a or (b || c)
``````

``````(a or b) || c
``````

Just like

``````1 + 2 * 3
``````

is evaluated as:

``````1 + (2 * 3)
``````

because `+` has lower precedence than `*`.

But it doesn't change the order of evaluation. `1` is still evaluated before `2 * 3`.

Also note that due to `or`'s very low precedence

``````p a or b || c
``````

is evaluated as:

``````(p a) or (b || c)
``````

Neither `b` nor `c` will ever be printed this way.