Maybe, !Maybe

Have you ever had to turn the following:

post.author.name

Into some awful nil check like this?

post.author.name if post.author
 #or
post.author && post.author.name
 #or
post.author.name unless post.author.nil?
 #or
post.author ? post.author.name : 'O Nameless One'

This code does not inspire to say the least.

Today I learned of the black hole null object from Avdi Grimm and it really made my day. Where has this been all my life? This is a simple class, which always returns itself, and returns true for nil?

class NullObject
  def method_missing(*args, &block)
    self
  end
  
  def nil?; true; end
end

Since the NullObject returns self from every call, an entire chain of calls silently fails:

n = NullObject.new
n.these.are.a.chain.of.calls => #<NullObject>

This is truly marvelous when combined with a Maybe object:

def Maybe(value)
  value.nil? ? NullObject.new : value
end

Now our hesitant code can become:

Maybe(post.author).name

The only problem is any object, by itself, will evaluate to truthy. You must use .nil? in conditionals (or create more methods, such as present?):

author = Maybe(post.author)
if author.nil?
  # do something intelligent
end

More details can be found on Avdi's blog. Also, look at the naught gem.

comments powered by Disqus