What does !! mean in ruby?
I’m new to Ruby and can’t find anywhere description of what “!!” means.
Here’s an example:
def signed_in? !!current_user end
If this is a double negative, why not to say:
def signed_in? current_user end
In most programming languages, including Ruby,
! will return the opposite of the boolean value of the operand. So when you chain two exclamation marks together, it converts the value to a boolean.
In Ruby (and many other languages) there are many values that evaluate to
true in a boolean context, and a handful that will evaluate to false. In Ruby, the only two things that evaluate to
false (itself) and
If you negate something, that forces a boolean context. Of course, it also negates it. If you double-negate it, it forces the boolean context, but returns the proper boolean value.
"hello" #-> this is a string; it is not in a boolean context !"hello" #-> this is a string that is forced into a boolean # context (true), and then negated (false) !!"hello" #-> this is a string that is forced into a boolean # context (true), and then negated (false), and then # negated again (true) !!nil #-> this is a false-y value that is forced into a boolean # context (false), and then negated (true), and then # negated again (false)
In your example, the
signed_in? method should return a boolean value (as indicated by convention by the
? character). The internal logic it uses to decide this value is by checking to see if the
current_user variable is set. If it is set, it will evaluate to
true in a boolean context. If not, it will evaluate as false. The double negation forces the return value to be a boolean.
!! 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
false otherwise. The second will negate that again so that you get the boolean value of the argument,
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
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
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
As you rightly understood it is a double-negative use of the
! operator. That said, while it can be a shorthand way to check for whether a variable can be nil or not, IMO that’s too concise. Take a look at this and this post. Note that in Ruby, testing something to nil will evaluate to false.