Just wondering what !!
is in Ruby.
8 Answers
Not not.
It's used to convert a value to a boolean:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
It's usually not necessary to use though since the only false values to Ruby are nil
and false
, so it's usually best to let that convention stand.
Think of it as
!(!some_val)
One thing that is it used for legitimately is preventing a huge chunk of data from being returned. For example you probably don't want to return 3MB of image data in your has_image?
method, or you may not want to return your entire user object in the logged_in?
method. Using !!
converts these objects to a simple true
/false
.

- 178,991
- 47
- 309
- 337
-
8It is not a bad practise to use this. Double bang is often used in predicates ( methods ending with ? ) to return an explicitly boolean value. – Swanand Mar 26 '10 at 10:12
-
6Alex, you don't really need to worry about returning large objects, as Ruby will return a reference, not a copy of the object. – DSimon Apr 09 '12 at 22:40
-
10@DSimon, sometimes you do need to worry about large objects, as when printing or logging a value during debugging. – Wayne Conrad Jun 09 '12 at 12:08
-
Why not just return `.nil?` instead of using `!!`? Is there a difference? – ashes999 Sep 03 '14 at 13:52
-
4There is a difference when your value is a booelan. `!!true #=> true` and `true.nil? #=> false` – Alex Wayne Sep 03 '14 at 16:32
-
Double banging is almost never actually necessary. The Ruby interpreter will always evaluate the truth value of the expression the same way with or without the double bang. As such, double banging just introduces more computation for no technical gain. (The gain lies in appeasing [some] human minds.) In addition to the point made about logging by Wayne Conrad: There is actually [at least] one place where double banging is necessary, though: When you are converting to_json, nil will go to null, so if you want the value to actually be true or false in JSON, you need to double bang. – Pistos Jul 20 '16 at 17:38
It returns true
if the object on the right is not nil
and not false
, false
if it is nil
or false
def logged_in?
!!@current_user
end

- 95,083
- 20
- 220
- 214

- 6,108
- 1
- 37
- 61
!
means negate boolean state, two !
s is nothing special, other than a double negation.
!true == false
# => true
It is commonly used to force a method to return a boolean. It will detect any kind of truthiness, such as string, integers and what not, and turn it into a boolean.
!"wtf"
# => false
!!"wtf"
# => true
A more real use case:
def title
"I return a string."
end
def title_exists?
!!title
end
This is useful when you want to make sure that a boolean is returned. IMHO it's kind of pointless, though, seeing that both if 'some string'
and if true
is the exact same flow, but some people find it useful to explicitly return a boolean.

- 95,083
- 20
- 220
- 214

- 54,010
- 13
- 102
- 111
-
it seems to me like just a faster way than using an if statement or a ternary operator. Since you can't just return `title`, may as well do the closest thing to it... I suppose – Carson Myers Mar 26 '10 at 07:22
Note that this idiom exists in other programming languages as well. C didn't have an intrinsic bool
type, so all booleans were typed as int
instead, with canonical values of 0
or 1
. Takes this example (parentheses added for clarity):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
The "not-not" syntax converts any non-zero integer to 1
, the canonical boolean true value.
In general, though, I find it much better to put in a reasonable comparison than to use this uncommon idiom:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious

- 10,689
- 4
- 41
- 50
-
Or just if (x). !! is useful when you need to get either 0/1. You may or may not consider (x) ? 1 : 0 clearer. – derobert Feb 08 '09 at 08:44
It's useful if you need to do an exclusive or. Copying from Matt Van Horn's answer with slight modifications:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
I used it to ensure two variables were either both nil, or both not nil.
raise "Inconsistency" if !!a ^ !!b

- 1
- 1

- 78,473
- 57
- 200
- 338
It is "double-negative", but the practice is being discouraged. If you're using rubocop, you'll see it complain on such code with a Style/DoubleNegation
violation.
The rationale states:
As this is both cryptic and usually redundant, it should be avoided [then paraphrasing:] Change
!!something
to!something.nil?

- 9,600
- 5
- 51
- 54
-
1
-
@Doug If you know you have a boolean value, it's redundant (just use the value). If you don't, you can use `!(foo.nil? || foo == false)` — more verbose, yes, but less cryptic. – David Moles May 28 '20 at 23:54
Understanding how it works can be useful if you need to convert, say, an enumeration into a boolean. I have code that does exactly that, using the classy_enum
gem:
class LinkStatus < ClassyEnum::Base
def !
return true
end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
def !
return false
end
end
class LinkStatus::Confirmed < LinkStatus
def !
return false
end
end
class LinkStatus::Denied < LinkStatus
end
Then in service code I have, for example:
raise Application::Error unless !!object.link_status # => raises exception for "No" and "Denied" states.
Effectively the bangbang operator has become what I might otherwise have written as a method called to_bool.

- 3,597
- 1
- 26
- 38
Other answers have discussed what !!
does and whether it is good practice or not.
However, none of the answers give the "standard Ruby way" of casting a value into a boolean.
true & variable
TrueClass
, the class of the Ruby value true
, implements a method &
, which is documented as follows:
Returns
false
ifobj
isnil
orfalse
,true
otherwise.
Why use a dirty double-negation when the standard library has you covered?

- 2,892
- 2
- 26
- 43