Singleton method vs. class method

Most of what happens in Ruby involves classes and modules, containing definitions of instance methods

class C
  def talk
    puts "Hi!"
  end
end

c = C.new
c.talk
Output: Hi!

But as you saw earlier (even earlier than you saw instance methods inside classes), you can also define singleton methods directly on individual objects:

obj = Object.new
def obj.talk
  puts "Hi!"
end
obj.talk
#Output: Hi!

When you define a singleton method on a given object, only that object can call that method. As you’ve seen, the most common type of singleton method is the class method—a method added to a Class object on an individual basis:

class Car
  def self.makes
    %w{ Honda Ford Toyota Chevrolet Volvo }
  end
end

But any object can have singleton methods added to it. The ability to define method- driven behavior on a per-object basis is one of the hallmarks of Ruby’s design.

Singleton classes

Singleton classes are anonymous: although they’re class objects (instances of the class Class ), they spring up automatically without being given a name. Nonetheless, you can open the class-definition body of a singleton class and add instance methods, class methods, and constants to it, as you would with a regular class.

Note:

Every object has two classes:

■ The class of which it’s an instance

■ Its singleton class

----------------------------------------------------------------

At Last I would highly recommends you to watch.

1: The Ruby Object Model and Metaprogramming For detail info about singleton method vs. class method ruby

2: MetaProgramming - Extending Ruby for Fun and Profit - by Dave Thomas

Hope this help you!!!


In ruby class is an object as well. So, in your example classmethod is a singleton method for object C and singletonmethod is singleton method for object c.

I highly recommend book "Metaprogramming Ruby" by Paolo Perrotta.


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.

#<Instance:0x00000000e9ee68>

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
#<Instance:0x00000000e98d60>
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
 #<Class:#<String:0x00000000e8f0f8>>

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

However, one can also follow this syntax to defined a class method

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)

There is no difference. There are no class methods in Ruby. "Class method" is just a name that we humans call a singleton method if the object happens to be an instance of the Class class.

Tags:

Ruby

Singleton