2

I am confused. When I define a method in Object I can call it in Objects superclass BasicObject!

Like so:

class Object
  def object_method
    "object_method called"
  end
end

Object.superclass.respond_to? :object_method
# => true

Object.superclass.object_method
# => "object_method called"

I have expected that only derived classes inherit the new method!

P.S.: I come to this question from an exercise on rubymonk

.. implement a method superclasses inside Object ..

where the recursion stop criterion is "affected".

ovhaag
  • 1,168
  • 2
  • 9
  • 16

2 Answers2

3

As you can see, it is a derived class.

#ruby 1.8.7
Object.superclass
# => nil
nil.kind_of? Object
# => true

#ruby 2.0.0
Object.superclass
# => BasicObject 
BasicObject.kind_of? Object
# => true 
oldergod
  • 15,033
  • 7
  • 62
  • 88
  • Ok both is true: `Object.kind_of? BasicObject` => true and `BasicObject.kind_of? Object` => true – ovhaag Jun 04 '13 at 00:55
  • @ovhaag http://stackoverflow.com/questions/8894817/whats-the-difference-between-object-and-basicobject-in-ruby – oldergod Jun 04 '13 at 00:59
  • It continues to be surprising because "You can use BaseObject as a parent of your object in case if you don't need methods of Object" And then a new method in Object sort of monkeypatches BasichObject – ovhaag Jun 04 '13 at 01:13
  • @ovhaag Considering actual behavior, I think they meant "in case if you don't need *instance methods* of Object". – Jokester Jun 04 '13 at 01:17
  • @jokester In this case object_method is an instance method of Object – ovhaag Jun 04 '13 at 01:27
  • @ovhaag Yes, and not an instance method of BasicObject. I don't see much inconsistency here. – Jokester Jun 04 '13 at 01:36
  • @jokester the fog begins to lift. I'll sleep over it now. – ovhaag Jun 04 '13 at 01:52
3

When you call Object.superclass, you get an object that describes BasicObject class.

This object is an instance of Class class that inherits from Object. Therefore, it has all the methods that Object has, including the one you added.

However, instances of the BasicObject class do not have this method:

irb(main):122:0> Object.object_method
=> "object_method called"

irb(main):123:0> Object.new.object_method
=> "object_method called"

irb(main):124:0> Object.superclass.object_method  # Same as BasicObject.object_method
=> "object_method called"

irb(main):125:0> Object.superclass.new.object_method  # Same as BasicObject.new.object_method
NoMethodError: undefined method `object_method' for #<BasicObject:0x441743be>
        from (irb):125:in `evaluate'
        from org/jruby/RubyKernel.java:1065:in `eval'
        from org/jruby/RubyKernel.java:1390:in `loop'
        from org/jruby/RubyKernel.java:1173:in `catch'
        from org/jruby/RubyKernel.java:1173:in `catch'
        from ~/.rvm/rubies/jruby-1.7.0/bin/irb:13:in `(root)'

Here is more stuff to meditate on:

irb(main):129:0> Object
=> Object
irb(main):130:0> Object.class
=> Class
irb(main):131:0> Object.new.class
=> Object
irb(main):132:0> Object.superclass
=> BasicObject
irb(main):133:0> Object.superclass.class
=> Class
irb(main):134:0> Object.superclass.new.class
NoMethodError: undefined method `class' for #<BasicObject:0x1c944d4a>
        from (irb):134:in `evaluate'
        from org/jruby/RubyKernel.java:1065:in `eval'
        from org/jruby/RubyKernel.java:1390:in `loop'
        from org/jruby/RubyKernel.java:1173:in `catch'
        from org/jruby/RubyKernel.java:1173:in `catch'
        from ~/.rvm/rubies/jruby-1.7.0/bin/irb:13:in `(root)'

Have fun!

Sergey Bolgov
  • 806
  • 5
  • 6