如何从NilClassinheritance或如何模拟类似的function

我只想使用Null对象设计模式,但我发现我可以inheritanceNilClass。

我可以写一个方法“nil?” 并返回false,但如果用户在下面编写代码,该怎么办

if null_object puts "shouldn't be here" end 

为了澄清我尝试做的是:

 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 

一种可能对你有用的方法是覆盖方法#nil? 在你的Null对象中。 这意味着在你的代码中测试null你必须使用obj.nil? 而不只是检查obj存在。 这可能是合理的,因为您可以区分nil和null。 以下是一个例子:

 class NullClass def nil? true end def null_behavior puts "Hello from null land" end end 

inheritance将起作用:

 class NewClass < NullClass end 

使用如下:

 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 

输出:

 obj is nil Hello from null land 

只记得使用#.nil? 对于任何需要Null和Nil为false-ish的检查。

这条线下面是我错误的初步答案

 CustomNil = Class.new(NilClass) class CustomNil def self.new ###!!! This returns regular nil, not anything special. end end 

[为简洁而删除的测试]

使用风险由您自己承担。 我还没有研究过这可能会导致什么副作用,或者它是否能达到你想要的效果。 但它似乎确实有一些零行为

我不认为Ruby实际上允许你从NilClassinheritance并基于它创建一个对象:

 class CustomNilClass < NilClass end custom_nil_object = CustomNilClass.new # => NoMethodError: undefined method `new' for CustomNilClass:Class 

我没有inheritanceNilClass而是执行以下操作

 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 

这为您提供了任何已经修补到NilClass上的自定义方法(例如ActiveSupport的blank?nil? )。 您当然也可以添加自定义空对象行为,或者更改method_missing以不同方式处理其他调用(这个返回NullObject以进行链接,但您可以返回nil例如)。