All objects are instances of a class. However, that is not the whole truth. In Ruby, every object also has a somewhat hidden singleton class.
This is what allows methods to be defined on individual objects. The singleton class sits between the object itself and its actual class, so all methods defined on it are available for that object, and that object only.
object = Object.new
def object.exclusive_method
'Only this object will respond to this method'
end
object.exclusive_method
# => "Only this object will respond to this method"
Object.new.exclusive_method rescue $!
# => #<NoMethodError: undefined method `exclusive_method' for #<Object:0xa17b77c>>
The example above could have been written using define_singleton_method
:
object.define_singleton_method :exclusive_method do
"The method is actually defined in the object's singleton class"
end
Which is the same as defining the method on object
's singleton_class
:
# send is used because define_method is private
object.singleton_class.send :define_method, :exclusive_method do
"Now we're defining an instance method directly on the singleton class"
end
Before the existence of singleton_class
as part of Ruby's core API, singleton classes were known as metaclasses and could be accessed via the following idiom:
class << object
self # refers to object's singleton_class
end