Coercing nil/obj to false/true

I know this probably comes up a lot, but I could not Google the exact
question as I’m formulating it.

Is there a way to avoid this idiom?

def is_there_one(whatever)
!some_call_to_lib_that_returns_object_or_nil(whatever).nil?
end

The above code tersely coerces a result to a boolean value, but it’s
hard to read, because it’s a double negative, and the “!” negative is
lexically separated from the “nil?” negative.

I occasionally do this instead:

x = some_call_to_lib_that_returns_object_or_nil
x.nil?

That’s more readable for me, but more verbose, and I can never decide
what to name “x.”

I can add something like this to my codebase, but I’m wondering if
something similar is already built in:

def to_boolean x
return !x.nil?
end

def is_there_an_x_like(whatever)
to_boolean(some_call_to_lib_x_that_returns_object_or_nil(whatever))
end

def is_there_a_y_like(whatever)
to_boolean(some_call_to_y_lib_that_returns_object_or_nil(whatever))
end

Finally, I can just have my method return obj or nil, and let the
callers use it in boolean expressions, but my fear there is that I set
the wrong expectation for the caller, if I later return a different
object, when my intention is only to indicate whether a query succeeds
or not. (You guessed it, this is motivated by ActiveRecord, but it’s
really a Ruby question.)

Thoughts?

2010/3/30 Steve H. [email protected]:

Is there a way to avoid this idiom?

def is_there_one(whatever)
!some_call_to_lib_that_returns_object_or_nil(whatever).nil?
end

Finally, I can just have my method return obj or nil, and let the
callers use it in boolean expressions, but my fear there is that I set
the wrong expectation for the caller, if I later return a different
object, when my intention is only to indicate whether a query succeeds
or not. (You guessed it, this is motivated by ActiveRecord, but it’s
really a Ruby question.)

Your method’s documentation and naming the method with a question mark
at the end will help avoid this. I would be more concerned with
leaking internal information. That’s why people often do this in
order to force conversion to true / false:

def is_there_one? whatever
!! some_call_to_lib_that_returns_object_or_nil(whatever)
end

If the call is expensive then I’d just return whatever is found and
let the caller check for nil in one of the many ways.

Btw, databases typically return always a collection - albeit it might
be empty. That depends on your mechanics in the invoked method of
course.

Kind regards

robert

On Mar 29, 10:30 pm, Steve H. [email protected] wrote:

I can add something like this to my codebase, but I’m wondering if
something similar is already built in:

def to_boolean x
return !x.nil?
end

If you really, really need exactly true or false based on the
truthiness of the value, just do:
!!x

However, I would have all your methods return either a useful value or
nil (or when appropriate, false), and just use that value in all your
boolean expressions.

For example, imagine an array-based stack. You could write:
def top?
!self.last.nil?
end
but I would instead recommend just writing:
def top
self.last
end
and let your users do:
if recent = my_stack.top
# do something with recent
end

On Mar 30, 12:17 am, Robert K. [email protected] wrote:

object, when my intention is only to indicate whether a query succeeds
or not. (You guessed it, this is motivated by ActiveRecord, but it’s
really a Ruby question.)

Your method’s documentation and naming the method with a question mark
at the end will help avoid this. I would be more concerned with
leaking internal information.

Yep.

That’s why people often do this in
order to force conversion to true / false:

def is_there_one? whatever
!! some_call_to_lib_that_returns_object_or_nil(whatever)
end

Ok, thanks, I find that more readable than !foo.nil?.

If the call is expensive then I’d just return whatever is found and
let the caller check for nil in one of the many ways.

Btw, databases typically return always a collection - albeit it might
be empty. That depends on your mechanics in the invoked method of
course.

Yep, understood, but ActiveRecord returns nil or object when you pass
find the :first parameter. It’s useful in some situations where you
just want to check that a record has at least one active child,
without caring about the children themselves, such as when you are
cleaning up “parent” objects that have been orphaned.

On Tue, Mar 30, 2010 at 3:17 AM, Robert K.
[email protected] wrote:

the wrong expectation for the caller, if I later return a different
!! some_call_to_lib_that_returns_object_or_nil(whatever)
end

I almost never find that I need to ‘force’ a ‘true’ boolean value in
Ruby.

I pretty much agree with Koz about this.
http://www.therailsway.com/2007/8/1/dangers-of-cargo-culting


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale