p parent.class #=> NilClass # ok.
p !!parent # => false # as expected.
p parent.object_id # => 17006820 # should be 4开发者_StackOverflow社区
p parent && parent.foo # => NoMethodError foo # should be nil-guarded
Where does this object come from?
Possibly something like this:
class BlankSlate
instance_methods.each do |m|
# Undefine all but a few methods. Various implementations leave different
# methods behind.
undef_method(m) unless m.to_s == "object_id"
end
end
class Foo < BlankSlate
def method_missing(*args)
delegate.send(*args)
end
def delegate
# This probably contains an error and returns nil accidentally.
nil
end
end
parent = Foo.new
p parent.class
#=> NilClass
p !!parent
#=> false
p parent.object_id
#=> 2157246780
p parent && parent.foo
#=> NoMethodError: undefined method `foo' for nil:NilClass
Creating BlankSlate
or BasicObject
is a common pattern (before it was added to core Ruby as of version 1.9). It serves to create objects that will do something special with any method they are sent, or heavily delegate their behaviour to a different class. The downside is that it may introduce strange behaviour like this.
精彩评论