How to inherit from NilClass or how to simulate similar function

*爱你&永不变心* 提交于 2019-11-30 15:58:41

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.

Below this line was my WRONG initial answer

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

I don't think Ruby actually allows you to inherit from NilClass and create an object based on it:

class CustomNilClass < NilClass
end

custom_nil_object = CustomNilClass.new
# => NoMethodError: undefined method `new' for CustomNilClass:Class

Instead of inheriting from NilClass I do the following

class NullObject < BasicObject
  include ::Singleton

  def method_missing(method, *args, &block)
    if nil.respond_to? method
      nil.send method, *args, &block
    else
      self
    end
  end
end

This gives you any custom method that have been monkey patched onto NilClass (such as ActiveSupport's blank? and nil?). You can also of course add custom null object behaviors, or change method_missing to handle other calls differently (this one returns the NullObject for chaining, but you could return nil for example).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!