Blog posts for Ruby, Ruby on rails and Linux.

Go back to all blogs

Getting Started with Null Object Pattern in Ruby

Kapil Raj Nakhwa2016-Jan-31

Often we have conditions when we as ruby programmers are hammered with whiny nil problems. We are hammered with exceptions where somewhere in the code some method is being called  on the nil object. We all have faced scenarios where a code is working in some set of data but when shipped to production it breaks down because somewhere some data is missing . A simple condition might be as following.

some_object.some_method 

blows up with undefined method some_method for nil . 

The first step in solving this would be to implement try . 

some_object.try(:some_method)

But still is has a serious code smell . When there are many missing values concatenated then this becomes a really contagious nil . 

You can read more about nil being contagious here : 

Well the best solution would be to implement the Null Object Pattern . 

(if you would like to learn more in detail about Null Object Pattern click here ) .


Here is an example to help further explain it . 

Consider the following case where i am searching for some reward fees to a customer based on the pay type . 

class RewardFee < ActiveRecord::Base

....

end

reward_fee = RewardFee.find_by_pay_type( pay_type)


Now, it might not be unlikely that we have something like this in our code. 


reward_feerate

This would work fine as long as pay_type value is in the database. If it is not . It will return the expected nil value. 


as soon as reward_fee is nil, The above line reward_fee.discounted_rate will throw an exception.

Now consider the following implementation with the Null Object Pattern 

class RewardFee < ActiveRecord::Base

  PAY_TYPE_CREDIT_CARD = "credit card"

  def self.grab_by_pay_type(pay_type)

    super || NullRewardFee.new

  end

end

class NullRewardFee

  def discounted_rate

    0

  end

end

and our previous use cases. 


reward_fee = RewardFee.grab_by_pay_type( pay_type)

reward_fee.discounted_rate

Not no exception would be raised , as the reward_fee would at least return a NullRewardFee with the discounted_rate implemented in it to return 0 . 

Hence, We save a lot of headache of data coupled code and some unwanted edge cases of failure. 

Further references

http://c2.com/cgi/wiki?NullObject

http://c2.com/cgi/wiki?NullObjectImplementation

http://c2.com/cgi/wiki?NullObjectExamples


Tags: ruby,null,null object,design patterns,null object pattern,code smell,code,nil

Go back to all blogs
Never miss a post on new ruby and rails tips