---
title: 'Back to Basics: Boolean Expressions'
teaser: Write Boolean expressions using operators instead of if/else for a more readable
  outcome.
tags: back to basics,ruby,development,web
author: Joël Quenneville
published_on: 2021-06-28
---

<blockquote>
  <p>If your only tool is a hammer, then every problem looks like a nail<p>
  <cite>Folk saying</cite>
</blockquote>

`if` / `else` expressions are a powerful tool that allow us to express
conditional logic. However, when it comes to returning Booleans they are
generally the wrong tool for the job. They can be redundant or, worse, obscure
the meaning of what is being done.

## Identity

This is a mistake I often see brand new programmers fall into. If you're looking
to write an if/else, it's natural to express "admins can edit and others cannot"
as the following conditional:

```ruby
def can_edit?
  if admin?
    true
  else
    false
  end
end
```

On closer inspection though, we can see that the conditional code is redundant.
It just returns the value that the Boolean already holds. Instead, we can return
the Boolean directly without doing any logic.

```ruby
def can_edit?
  admin?
end
```

## Negation

This one is very similar to the "identity" conditional shown above but the
branches are flipped. When `admin?` is true we return false and when it is false
we return true.

```ruby
def reader?
  if admin?
    false
  else
    true
  end
end
```

We have an operator the does the same thing: `!` (NOT). Much shorter and easier
to read now!

```ruby
def reader?
  !admin?
end
```

## Early returns

Ruby syntax allows for combining early returns with a postfix conditional to
create really terse conditional logic. If you're using this approach to return
different Booleans, you're probably better off using the Boolean operations
instead. Consider the following:

```ruby
def reader?
  return false if admin?
  true
end
```

This is the same negation conditional we saw above. It's much terser but also
really hard to read. As before, this is re-implementing the `!` (NOT) operator.

```ruby
def reader?
  !admin?
end
```

## Multiple variables

Boolean methods expressed as a series of early returns  can be very difficult to
read, especially once you have a few different variables. Often, they may hide
some very basic Boolean operations. Consider the following:

```ruby
def can_edit_admin_post?
  return owner? unless admin?
  true
end
```

It's really tricky to follow the interplay between the two conditions. Who is
able to edit admin posts and under what conditions? Even with only two variables
I struggle to answer that question.

It turns out that this conditional code was re-implementing the Boolean `||`
(OR) operator. Now try and explain who can edit. Much easier!

```ruby
def can_edit_admin_post?
  owner? || admin?
end
```

Let's scale it up to 3 variables. Here's an example inspired by some code on a
recent project that really confused me 😱🙀😱

```ruby
def can_edit?(article)
  return false unless article.status == "published"
  return true if admin?
  return false unless article.authored_by?(self)
  true
end
```

## Truth tables

So you've encountered a confusing Boolean conditional method (maybe you've
written it yourself!). How can you get a grasp of what is happening? One tool I
like is the **truth table**. Create columns for all the inputs covering all the
combination of true/false values. Then calculate the outcome for each row and
add it in the final column. The result will look as follows:

| `owner?` | `admin?` | `can_edit_admin_post?` |
|----------|----------|------------------------|
| false    | false    | false                  |
| false    | true     | false                  |
| true     | false    | false                  |
| true     | true     | true                   |

I find this very useful to get a better overview of how a method behaves.
Sometimes patterns for common operations stand out. In the example above, the
output column is always false except for the row that is all true values. That's
the same pattern as for `&&` as can be seen in the truth table below.

| `a`   | `b`   | `a && b` |
|-------|-------|----------|
| false | false | false    |
| false | true  | false    |
| true  | false | false    |
| true  | true  | true     |

## Write Boolean expressions

The operators `!`, `||`, and `&&` give us powerful tools for working
with Boolean expressions. Add them to your toolbelt! The next time you are
writing a method that returns Booleans you'll have something other than if/else
to reach for.
