Saving the world

Be sure to check out our application, join some causes, spread the word and help save the world: causes.com.

We're Hiring!

Check out some of the listings in our jobs section.

Grab our feed

Stay up to date with the Causes engineering team by subscribing to our feed.

DRYing Out Deep Checks

We found ourselves very often writing code with conditions that looked like:

if object && object.child && object.child.valid?
  do_something(object.child)
end

In this case all we really want to do is verify that object.child.valid? returns true, but writing

if object.child.valid?

left us vulnerable to the dreaded

# NoMethodError: undefined method `child' for nil:NilClass

The solution? The try method, which accepts a block and returns the result of that block, or nil if NoMethodError is raised. Thus our conditional becomes

if try { object.child.valid? }

which represents what we’re trying to validate without the cruft of explicitly validating all of the implicit prerequisites.

What does the implementation look like? It turns out that it’s dirt simple:

def try
  yield
rescue NoMethodError
  nil
end

A second pass allows you to define other exceptions that you think are likely but don’t care about:

def try(exceptions = [NoMethodError])
  exceptions = [exceptions].flatten
  yield
rescue Exception => ex
  raise ex if !exceptions.any? {|ec| ex.is_a?(ec)}
  nil
end

Thats it. Simple, clean, and dries up a very common idiom in our codebase.

Leave a Reply