As discussed in the forums, it's a bit unintuitive that given password : Crypto::Bcrypt::Password and string : String, password == string will work but string == password won't.
Two solutions:
String==#(other : Crypto::Bcrypt::Password) so it's commutativeis_password? as an alias, but verify, check or matches? might be equally good.I'm not sure which approach is better. I think the second one is better because it's also more type-safe. You can do password == 1.23 and it will still compile, but it's obviously incorrect. You can even do password == password and it will return true, but it makes little sense.
Thoughts?
Crypto::Bcrypt::Password#matches?(string) reads pretty good.
Please remove == here
Just gotta make sure that password == 1.23 will not compile
because normally if there is no such method it will just always return false...
and old code would keep "working"

7 hours ago?! GH is getting moar _fun_ every day... 馃う鈥嶁檪
If we go with #matches?, better to use #match? or #match. This methods already exist for others objects, better to choose this ones for consistency.
Bool)Crypto::Bcrypt::Password#match?(password : String) : Bool is good idea.
@j8r You're comparing apples to oranges. String/Regex#match is an action, matches? here is question, so the proper form would be a 3rd person (see Enumerable#includes? for instance).
I don't like match because usually match is used to match something against a pattern, and a password is definitely not a pattern.
I'd go with is_password? or verify (or verify?)
@bew It is actually matching the password against the stored hash by hashing it itself. So #matches? would conceptually work. But I'd also prefer #verify. That's also the term used in the methods description.
Just gotta make sure that password == 1.23 will not compile
I was going to say that this is kind of impossible to do, but no:
class Foo
def ==(other : Foo)
true
end
def ==(other)
{% raise "can't compare!" %}
end
end
foo = Foo.new
foo == 1
:-)
So I guess we can deprecated == in a first pass, then indefinitely make it a compile-error to compare it to a string.
It makes no sense to have sometimes 3rd person and sometimes not.
Like regex, it can be Crypto::Bcrypt::Password#match, with eventually Crypto::Bcrypt::Password#=~.
Edit: verify is nevertheless better I think, more explicit.
@j8r this _sometimes_ is quite specific - String/Regex#match returns MatchData, whereas ? methods are returning Bool.
or are nillable @Sija , there is no proper rule written anywhere for that. ([]?, to_i? etc)
@j8r yes, they're nillable since they return a value, not an answer (Bool).
@straight-shoota verify sounds good, yet since it returns Bool I'd call it verify?.
I don't mind the overridden ==, I'd just make it commutative
The problem with == is that you can basically pass anything, an int, a float, a bool, to == and it will compile, but it won't give the correct result. That makes it not type safe. And here we aren't really comparing stuff, we want to know if a password matches an encoded version of it, which isn't exactly "equality".
The concept of a password matching an encoded version would probably be better encoded in the =~ operator. But it's not type safe either and commutativity isn't really necessary anyway.
So, using a dedicated method is IMO the best solution.
And I'd go with #verify for that.
@Sija The ? suffix is not used to indicate a Bool return type, but specifically a predicate method. #verify is more an action than a predicate. If we wanted to use a predicate, it would be #verifies?. But I think an action term fits better here.
Let's go with #verify? with or without the question mark.
Most helpful comment
The problem with
==is that you can basically pass anything, an int, a float, a bool, to==and it will compile, but it won't give the correct result. That makes it not type safe. And here we aren't really comparing stuff, we want to know if a password matches an encoded version of it, which isn't exactly "equality".