如何从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
例如)。