Writing NullObject in Ruby to please Rubocop gods

Lets get right to it. Here’s how one can write a NullObject in a modern, Rubocop-friendly manner:

class NullObject
  def method_missing method, *args, &block
    if respond_to? method
      nil
    else
      super
    end
  end

  def respond_to_missing? _name, _include_private = false
    true
  end
end

One of the things you should support is the fallback to super. I achieve that by the if/else block. In practice super is never reached, so this feels a little bit like a waste.

The other thing is to declare whether your object (NullObject) should respond to methods it doesn’t have. A true null object should respond to all methods, so I set respond_to_missing? to true.

Just for posterity, here’s how you could write specs for it:

describe NullObject do
  it 'returns nil for any method call' do
    null = NullObject.new

    expect(null.missing_method).to be_nil
    expect(null.something_other_missing_method(1, 2, 3)).to be_nil
  end

  it 'responds to missing methods' do
    null = NullObject.new

    expect(null.respond_to?(:missing_method)).to be true
  end
end

Additional reading about the NullObject pattern:

  • http://wiki.c2.com/?NullObject
  • http://www.virtuouscode.com/2011/05/30/null-objects-and-falsiness/

Published by

Paweł Gościcki

Ruby/Rails programmer.