tags:

views:

70

answers:

1
p parent.class #=> NilClass # ok.
p !!parent # => false # as expected.
p parent.object_id # => 17006820 # should be 4
p parent && parent.foo # => NoMethodError foo # should be nil-guarded

Where does this object come from?

+1  A: 

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.

molf
Nice one. (rdb:1) p Object.instance_method(:class).bind(parent).call YARD::StubProxy
Tass