Are class method and singleton method doing the same or different? Here is an example.
class C
def self.classmethod
puts \"class method #{self}\"
end
end
Since all methods are implemented and stored by the class definition, it should be impossible for an object to define its own methods. However, Ruby provides a way around this - you can define methods that are available only for a specific object. Such methods are called Singleton Methods.
class Instance
def instance_method
puts "instance method called"
end
end
in_obj = Instance.new
The above statement you a reference object of class Instance, you might get a different id.
#
let's call the instance method with the object and we will get output.
in_obj.instance_method
instance method called
Now, create the singleton method.
sin_obj = Instance.new
#
def sin_obj.singleton_method
puts "singleton method called"
end
calling the singleton method
sin_obj.sigleton_method
singleton method called
Here, the object sin_obj has the singleton method singleton_method. This is a singleton method because it belongs to just one instance of a class and will not be shared with others.
However, singleton methods contradict that instance objects cannot hold methods, only class definitions (objects of class Class) can. It happens that the truth is somewhere in-between. When you declare a singleton method on an object, Ruby automatically creates a class to hold just that method. This class is called the 'metaclass' of the object. All subsequent singleton methods of this object goes to its metaclass. Whenever you send a message to the object, it first looks to see whether the method exists in its metaclass. If it is not there, it gets propagated to the actual class of the object and if it is not found there, the message traverses the inheritance hierarchy. Let defined the class method in the same Instance class. Now, lets check the fact that I stats above with an example.
foo = "Hey I am a string"
def foo.foo_instance_method
p self.upcase
end
Verify the fact that signleton method definition goes to the meta class.
p foo.class.instance_methods.include?:foo_instance_method
false
p foo.metaclass.instance_methods.include?:foo_instance_method
true
p foo.metaclass.class
Class
p foo.metaclass
#>
Let look how meta class is implemented.
class Instance
def metaclass
class << self
self
end
end
end
The class << self syntax changes the current self to point to the metaclass of the current object. Since we are already inside an instance method, this would be the instance's metaclass. The method simply returns self which at this point is the metaclass of the instance.
A metaclass is almost a class in many respects. It however can't be instantiated. To check this see the example below.
a = Instance.new
a.metaclass.new
You will get is error when try to intantiate the meta class.
*TypeError: can't create instance of singleton class*
In Ruby, both 'metaclass' and 'singleton class' means the same. You'll find them being used interchangeably in Ruby literature.
class Instance
def self.class_method #instead one can use def Instance.class_method
puts "class method called"
end
end
class Instance
class << self
def show
puts "Class method show invoked"
end
end
end
calling class_method
Instance.class_method
class method called
Instance.show
Class method show invoked
It consists of building a new anonymous class only for the current object (self). To create the anonymous class, we use the << notation. Look closely how class method and singleton method are defined you find the difference. consider the example.
class Instance
puts self
def meth
p self
end
end
here, outside of meth method self is nothing but the class, inside an instance_method the self pointing to the current instance or object.
Additionally, You can also check that a method responds to a particular object or not.
p Instance.new.respond_to?(:singleton_method)
p Instance.new.respond_to?(:class_method)