Is it normal for methods with a question mark to return something that's truthy (for example, a number) to indicate that something is true, or should true
itself be returned?
Are there any examples of truthiness being used in the Ruby standard library or by Rails, for example?
Background: Someone wrote a String#int?
method in an answer to a separate question, which returned an integer to represent true, and nil
to represent false. Another user was surprised at not returning a boolean.
There are two answers to your question, and both are valid:
Technically, anything returning a
false
ornil
value acts as a false boolean when doing a conditional test, just as a non-nil ortrue
value acts as a true. So, the method in question will work correctly for most times you'd want to know if something is an integer.But stylistically a method that ends with '?' should return either a Boolean
true
orfalse
and only those.The method in question doesn't really play nicely with our expectations and fails the POLS ("principle of least surprise") because you can reasonably expect a Boolean value being returned, and get an integer or a nil. THAT could lead to unpleasant surprises in code when it fails with an unexpected
nil
or a Fixnum value.So, while it's a valid method, it's not a good method, and I would have brought it up in a code review. And that leads to a separate discussion of how subtle things like that can enhance or hurt code maintenance, but that's an entirely different discussion.
I renamed the method in question to remove the
?
, which was really not important to the question being answered. Scanning through the core functions that end in ?s, the only ones I spotted that returned data or nil were theadd?
anddelete?
methods on Set.It is usual for methods ending with
?
to return eithertrue
orfalse
but it is not systematic and no core method will assume it.An example in the core classes is
Numeric#nonzero?
which never returnstrue
orfalse
.The library
Set
hasadd?
anddelete?
too. I wishEnumerable#one?
returnednil
orfalse
to distinguish cases where the count is zero from when it is greater than one.A similar example are the comparison operators (
<
,>
, ...), which usually return onlytrue
orfalse
. Here again exceptions exist forModule
's operators that will returnnil
instead when the two modules are not related:Adding a ? to a method name in Ruby is idiomatic that the method will return true or false. Object#nil? is a good example. In fact, Object has a lot of good examples of truthiness checks.