Booleans in the BikeRoom

Zoe Friedman
3 min readMar 4, 2021

I used to skate by with a surface level understanding of Ruby boolean logic, occasionally confounded by what I thought “should” be happening. But I know now that I was missing something important. And that something was the order of operations.

A little context: my nyc apartment building has a bike room and lost all record of spot ownership. It’s been a wild west ever since. I set out to create a site for building management using Ruby to track who has which spot, who owns which bikes, and to identify which bikes ought not to be in which spots. All with the selfish intention of keeping people out my *amazing* spot once and for all.

With that in mind, check out two of my helper methods and their sweet booleans operators:

def check_owner(obj)obj && obj.user == current_userenddef can_altercheck_owner(@bike) || (@bike && is_admin?)end

So let’s talk about the basics:

  1. && — the “and” operator

When you are using “&&” it is important to note that if the left side of the comparison returns false, your computer will NOT EVEN LOOK at the right side. The comparison will immediately return false. In the above check_owner method, it first checks to see if the object even exists. If the object does not exist, this entire method will return false. If the object does exist, only then will it check to see if the users match.

2. || — the “or” operator

On their own, the *pipes* are straightforward enough. Similarly, they will first check the left side of the operator. If the the left side returns true, your computer WILL NOT EVEN LOOK at the right side of the operator. So whatever is on the right side better not be important if there’s any chance in hell that left side is returning true.

3. Multiple “&&” comparisons

true && true && true
=> true

Easy peasy. If all three things are true or have truthy values this will return true. If just one is false or falsey, this will return false.

4. Multiple “||” comparisons

false || false || true
=> true

Here you can see that from left to right, we’re checking for just one truthy value. Reminder, if the first or second value returns true, game over — your computer will not even check the rest.

5. Mixing “&&” and “||”

This is where it gets interesting:

2.6.1 :034 > false && true || true
=> true
2.6.1 :035 > false && (true || true)
=> false

Parenthesis can be crucial here!!! This is because there is an “order of operations” in place, similar to regular arithmetic. The computer first will evaluate the “and” operator and THEN evaluated the “or” operator. Using parenthesis is the only way to force the boolean to evaluate first.

This tripped me up when I had the following line of code. In this instance, there was no bike, but the admin was checking:

@bike && check_owner(@bike) || is_admin?
=> true

or

false && false || true
=> true

But, no! This *should have* returned false, right? Wrong. In this instance, I needed parenthesis:

@bike && (check_owner(@bike) || is_admin?)
=> false

If there was NO BIKE, I didn’t care who was checking. I needed the method to return false.

The side it’s on doesn’t matter. In Ruby, the “and” operator will always evaluate first.

true || true && false 
=> true

whereas:

(true || true) && false
=> false

Takeaways: Acknowledging orders of operations is essential when mixing boolean operators. Use parenthesis to help guide the journey.

For a full list of all operator precedence see this great Techotopia article.

--

--