public
Last active

A null object in Ruby with refinements

  • Download Gist
dependency.rb
Ruby
1 2 3 4 5
module Dependency
def self.give_me_the_nil
nil
end
end
nullobject.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
module NullObject
refine NilClass do
def method_missing(method, *args, &block)
self
end
 
def respond_to_missing?(*args)
true
end
 
def tap; self; end
end
end
 
 
 
# Ruby's nil now behaves like a Null Object, returning itself whenever a method
# is called. This means you don't have to check for presence anymore. No more
# `... unless value.nil?`! Dont worry, refinements are only valid on a per file
# basis. Your dependencies won't break, but the values they output in this file
# will be refined.
 
using NullObject
 
class Person
def fetch
@first_name = "john"
@last_name = "doe"
end
 
def first_name
@first_name.capitalize
end
 
def last_name
@last_name.capitalize
end
end
 
person = Person.new
p person.first_name # => nil
p person.last_name # => nil
 
person.fetch
 
p person.first_name # => "John"
p person.last_name # => "Doe"
 
 
 
# The tests are written for cutest (https://github.com/djanowski/cutest). They
# can be run as follows: `cutest nullobject.rb`. Dont forget to `gem install
# cutest`!
 
prepare { $test = 0 }
setup { nil }
 
test "should be falsey" do |x|
assert (not x)
end
 
test "should return nil when calling a method" do |x|
assert x.some_method.nil?
end
 
test "should return nil when #tapped" do |x|
x.tap { $test = 1 }
assert_equal $test, 0
end
 
test "should work on nil's returned from other libraries" do |x|
require_relative "dependency"
assert_equal Dependency.give_me_the_nil.some_method, x
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.