!!
is just !
(the boolean negation operator) written twice. It will negate the argument, then negate the negation. It's useful because you can use it to get a boolean from any value. The first !
will convert the argument to a boolean, e.g. true
if it's nil
or false
, and false
otherwise. The second will negate that again so that you get the boolean value of the argument, false
for nil
or false
, true
for just about everything else.
In Ruby you can use any value in an if
statement, e.g. if current_user
will execute if the current user is not nil
. Most of the time this is great because it saves us typing explicit tests (like if !current_user.nil?
, which is at least six characters longer). But sometimes it might be really confusing if you return an object when the method implies that it returns a boolean. Methods whose name ends with ?
should return truthy or falsy values, i.e. they return something that will evaluate to true
or false
. However, it can get really messy if signed_in?
returned a user object. For example if you're trying to debug why some code that uses signed_in?
doesn't work you will probably get really confused when a user object turns up where you expected true
or false
. In that situation it's useful to add !!
before the return
since that guaranteed that the truthy or falsy value will be returned as either true
or false
.