In Ruby, nil
and false
are falsey, and they are the only falsey values. Every other value is truthy, this includes true
(obviously), but also values that some other languages might not consider truthy such as 0
, 0.0
, ""
, []
, {}
, and so on.
There is also a naming convention in Ruby that methods whose primary purpose is to answer a Yes/No question are named ending with a question mark.
So, we have the method Integer#odd?
, for example, which (probably not surprising) returns true
if the receiver is odd and false
if the receiver is even, e.g.
1.odd? #=> true
2.odd? #=> false
It is, however, quite common, to convey some extra information using the return value of a purportedly boolean method. Actually, the most extreme example is not a method but the builtin unary prefix defined?
operator, which is a boolean operator that (at least in the most widely-used Ruby implementation) never actually returns a boolean!
The Language Specification (section 11.4.3.2 The defined?
expression) only guarantees that defined?
returns a truthy value or nil
, but it does not require that the falsey value be precisely the value false
. And many Ruby implementations use that fact to convey additional information to the programmer. For example, in YARV:
defined? foo #=> nil
def foo; end
defined? foo #=> 'method'
foo = 42
defined? foo #=> 'local-variable'
This is information that is useful for debugging purposes, but yet doesn't hurt when you use the defined?
operator in a conditional context like
def foo; end unless defined? foo
Returning nil
(the value representing the absence of a value) instead of false
for methods that ask for the existence of something is especially common.
In general, you are not supposed to do anything other with the return value than treat it as a truthy or falsey value, but you can inspect it for debugging purposes only.
In the Ruby community, this is considered to be completely normal, and there are methods in widely-used third-party libraries, in the standard libraries, and in the core library that do this, and the specification for those methods is often explicitly written in such a way to allow this, e.g. requiring only truthy or falsey values instead of true
or false
.
function foo() { return (a === b); }
instead.