Weird Ruby: Double Negation
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:
!!foo
This is a somewhat popular idiom to convert a value
to a boolean (true
or 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:
foo.!.!
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 false
and 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
return true
or 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
- Weird Ruby: Invoking Lambdas
- Weird Ruby: For Loops
- Weird Ruby: Array Multiplication
- Weird Ruby: Heredoc Delimiters
- Weird Ruby: Mixing Code and Data
- Weird Ruby: A Weird Way to Filter Out Elements
- Weird Ruby: Nil Conversions
- Weird Ruby: Fun with String#split
- Weird Ruby: Incrementing Strings
- Weird Ruby: The Double Aliased Enumerable Method
-
This idiom is also popular in the JavaScript world. ↩