I just want to use Null Object Design Pattern, but I found I can inherit from NilClass.
I can write a method "nil?" and return false but what if user write code below
if null_object
puts "shouldn't be here"
end
For clarify what I try to do is:
record = DB.find(1)
# if it can not find record 1, the bellow code should not raise exception
record.one_attr
# and what's more
if record
puts "shouldn't be here"
end
# I don't want to override all NilClass
An approach that may work for you is to overide the method #nil? in your Null object. This means that in your code to test for null you have to use obj.nil? and not just check for obj existence. This is probably reasonable, since you can distinguish between nil and null. Below is an example:
class NullClass
def nil?
true
end
def null_behavior
puts "Hello from null land"
end
end
Inheritance will work:
class NewClass < NullClass
end
Use like so:
normal = Class.new
null = NewClass.new
x = [normal, null]
x.each do |obj|
if obj.nil?
puts "obj is nil"
obj.null_behavior
end
end
Output:
obj is nil
Hello from null land
Just remember to use #.nil? for any checks that require Null and Nil to be false-ish.
CustomNil = Class.new(NilClass)
class CustomNil
def self.new
###!!! This returns regular nil, not anything special.
end
end
[tests deleted for brevity]
Use at your own risk. I haven't researched what side effects this may cause or whether it will do what you want. But it seems it does have some nil like behavior