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