Okay, so going through the https://www.railstutorial.org book, I’m on chapter 6, section 6.3.4 and I come across this “gem” (not the ruby gem).
!!user.authenticate("foobar") # returns true
Okay, so I get !false = true, and !!true = true, but what’s going on here?
Is it because the authenticate method can return false (when it fails to authenticate), so !user.authenticate("wrong pass") returns true, and !user.authenticate("right pass") would return false?
So you have to double the bang operators to get the desired boolean values? (that seems to be the case)
Good. I did understand it correctly. Thanks. I’m not sure I’d personally use my prior example all that often as it feels like you ask for an object but then you refuse to use it…
There is likely a better way of expressing intent here that the book hasn’t fully shown/suggested yet.
A common use of the double bang operator is to have your predicate methods return true or false, rather than truthy or falsy values. E.g.
class String
def contains?(val)
self.downcase.match(val)
end
end
p "Sitepoint".contains?("point") # => #<MatchData "point">
p "Sitepoint".contains?("overflow") # => nil
Compared with:
class String
def contains?(val)
!!self.downcase.match(val)
end
end
p "Sitepoint".contains?("point") # => true
p "Sitepoint".contains?("overflow") # => false
Check out the TrueClass which provides operators allowing true to be used in logical expressions.
You can also write the above as:
class String
def contains?(val)
true & self.downcase.match(val)
end
end
p "Sitepoint".contains?("point") # => true
p "Sitepoint".contains?("overflow") # => false