Singleton method vs. class method

后端 未结 5 841
一向
一向 2021-02-08 16:31

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         


        
相关标签:
5条回答
  • 2021-02-08 16:36

    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.

    0 讨论(0)
  • 2021-02-08 16:39

    They are relative notions; matter of perspective. What is its instance method from the point of view of a singleton class of class A is a class method from the point of view (of an instance) of A.

    0 讨论(0)
  • 2021-02-08 16:46

    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!!!

    0 讨论(0)
  • 2021-02-08 16:57

    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.

    0 讨论(0)
  • 2021-02-08 16:57

    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)
    
    0 讨论(0)
提交回复
热议问题