---
title: Clearer Conditionals using De Morgan's Laws
teaser:
tags: web,good code
author: Gabe Berke-Williams
published_on: 2013-12-20
---

Ever seen a hard-to-parse conditional like this?

    def allow_access_to_site?
      ! (signed_out? && untrusted_ip?)
    end

Let's use De Morgan's Laws to clean it up and see who actually has access to our
site.

## De Morgan's Laws

![''](https://images.thoughtbot.com/clearer-conditionals-using-de-morgans-laws/augustus_de_morgan.jpg)

Whoa, who's this De Morgan guy? [Augustus De Morgan][morgan], in addition  to
looking like a 19th-century [John C. Reilly][reilly], formulated two important
rules of logical inference. You can check out the formal definition on [the
Wikipedia page][wiki], but here they are in Ruby code:

    # First law
    !(a && b) == !a || !b
    # Second law
    !(a || b) == !a && !b

Well hey, it looks like we can use these on our gnarly conditional above. Let's try it.

## Law-abiding Ruby code

Recall that the original conditional was `! (signed_out? && untrusted_ip?)`.
Let's use the first law and puzzle it out.

    # Original
    ! (signed_out? && untrusted_ip?)
    # Conversion using first law. I've added parentheses for clarity.
    # a = signed_out?
    # b = untrusted_ip?
    (! signed_out?) || (! untrusted_ip?)

Here I notice that `! signed_out?` and `! untrusted_ip?` are double negatives:
*not* signed *out*, *not* *un*trusted IP. Now what they're really trying to say
is: signed *in*, *trusted* IP. Let's simplify further, using better method
names.

    # Simplify a: (! signed_out?) == signed_in?
    (signed_in?) || (! untrusted_ip?)
    # Simplify b: (! untrusted_ip?) == trusted_ip?
    (signed_in?) || (trusted_ip?)
    # Remove parentheses
    signed_in? || trusted_ip?

These methods, `signed_in?` and `trusted_ip?`, might exist and they might not.
Creating them is part of this refactoring. You might even end up removing the
`signed_out?` and `untrusted_ip?` methods in favor of these new,
positively-named methods.

And that's it. We took a hard-to-parse conditional and made it clearer and
easier-to-read using De Morgan's first law.

Before:

    def allow_access_to_site?
      ! (signed_out? && untrusted_ip?)
    end

After:

    def allow_access_to_site?
      signed_in? || trusted_ip?
    end

[morgan]: https://en.wikipedia.org/wiki/Augustus_De_Morgan
[reilly]: https://en.wikipedia.org/wiki/John_C._Reilly
[wiki]: https://en.wikipedia.org/wiki/De_Morgan%27s_laws
