3

Say I want to patch the Kernel module with one method I just came up with:

module Kernel
  def say_hello
    puts "hello world"
  end
end

I can now certainly do this:

Object.new.say_hello # => hello world

but I can also do the following which I normally shouldn't be able to do:

Object.say_hello # => hello world

Since Object includes Kernel it takes its instance methods and thus all Object instances should respond to say_hello. So far so good.

However Object.say_hello seems to be a class method which could only be justified if we had done something similar to this:

class << Object
  def say_hello
    puts "hello world"
  end  
end

Storing say_hello in Object's singleton class would allow us to use it as a class method but instead Kernel in just included in Object which shouldn't allow this behavior. But it does. Does anybody have a clue why?

Thanks

stratis
  • 7,750
  • 13
  • 53
  • 94

1 Answers1

5

Kernel is just included in Object [...]

That is correct.

[...] which shouldn't allow this behavior.

You overlook that classes are objects, too.


Let's see where the say_hello method comes from if obj is an instance of Object:

obj = Object.new

obj.method(:say_hello)
#=> #<Method: Object(Kernel)#say_hello>

Just as expected. obj is an instance of Object and Object includes Kernel:

obj.class.include? Kernel
#=> true

obj.class.ancestors
#=> [Object, Kernel, BasicObject]

Now let's see what happens if obj is the class Object:

obj = Object

obj.method(:say_hello)
#=> #<Method: Class(Kernel)#say_hello>

This time obj is an instance of Class and Class also includes Kernel:

obj.class.include? Kernel
#=> true

obj.class.ancestors
#=> [Class, Module, Object, Kernel, BasicObject]

Ruby's documentation notes that class methods are in fact just instance methods defined on the class object: (emphasis added)

class C
  def self.my_method
    # ...
  end
end

However, this is simply a special case of a greater syntactical power in Ruby, the ability to add methods to any object. Classes are objects, so adding class methods is simply adding methods to the Class object.

Stefan
  • 109,145
  • 14
  • 143
  • 218