# Clearer Conditionals using De Morgan's Laws

Gabe Berke-Williams

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

Whoa, who’s this De Morgan guy? Augustus De Morgan, in addition to looking like a 19th-century John C. Reilly, formulated two important rules of logical inference. You can check out the formal definition on the Wikipedia page, 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 untrusted 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
``````

## What’s next

If you found this useful, you might also enjoy: