Welcome to another installment of the “Weird Ruby” series! Today we’re going to continue exactly where we left off last time. In other words - we’re going to discuss this bit of slightly weird Ruby code:
This is a somewhat popular idiom to convert a value
to a boolean (
false).1 Believe it or not the idiom is known
as “double negation”. Let’s take a look at how this behaves:
!!10 # => true !!true # => true !!false # => false !!nil # => false
There’s nothing really special about the code once you know that
! is just a regular method in
Ruby. Double negation is nothing but a syntactic sugar for:
It’s important to understand that
!! are just two negations combined and not some special operator. I’ve seen
people confused about this, so I wanted to highlight it here.
Another source of confusion about double negation is that in some programming languages you can’t use
! with non-boolean values:
// Java // syntax error var foo = 5; !!foo; // double negation works only for boolean values // which renders it useless var foo = true; !!foo;
So, now we understand how
!! works, but you might be wondering if it’s any useful.
After all, we know that in Ruby every object except
nil is logically true (a.k.a.
truthy). This means it’s unlikely
we’ll need to convert objects explicitly to boolean values. Just consider this trivial example:
# redundant conversion do_something if !!foo # idiomatic Ruby do_something if foo
In practice there’s just one place where we really want to convert something to a boolean and that’s the return value of
predicate methods. While it’s not strictly mandated by Ruby, there’s a strong convention that a predicate method should
false and the
!! trick is useful there:
def awesome? # ... !!result end # an alternative approach def awesome? # ... !result.nil? end
I’ve never had any issues writing
!foo.nil?, so I rarely use
!!, but the option is there if you need/like it.
This discussion reminded me that it would have been nice if Ruby had a
to_bool method or something like this. Something as simple as:
class Object def to_bool !!self end end 5.to_bool # => true nil.to_bool # => false
Simple enough, but probably an overkill given the limited usage of “real” boolean values in Ruby.
That’s all for today! I hope it was weird and useful enough for you! Keep hacking!
Articles in the Series
- Weird Ruby: Pure Object-Oriented Negation
- Weird Ruby: Positive and Negative Strings
- Weird Ruby: Double Negation
- Weird Ruby: Single-quoted Heredocs
- Weird Ruby: Block Comments
- Weird Ruby: Zeroing in on a Couple of Numeric Predicates