class << self idiom in Ruby

后端 未结 6 1535
时光说笑
时光说笑 2020-11-22 13:51

What does class << self do in Ruby?

6条回答
  •  难免孤独
    2020-11-22 14:18

    Usually, instance methods are global methods. That means they are available in all instances of the class on which they were defined. In contrast, a singleton method is implemented on a single object.

    Ruby stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.

    If multiple singleton methods are defined within a single object, they are all stored in the same metaclass.

    class Zen
    end
    
    z1 = Zen.new
    z2 = Zen.new
    
    class << z1
      def say_hello
        puts "Hello!"
      end
    end
    
    z1.say_hello    # Output: Hello!
    z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…
    

    In the above example, class << z1 changes the current self to point to the metaclass of the z1 object; then, it defines the say_hello method within the metaclass.

    Classes are also objects (instances of the built-in class called Class). Class methods are nothing more than singleton methods associated with a class object.

    class Zabuton
      class << self
        def stuff
          puts "Stuffing zabuton…"
        end
      end
    end
    

    All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.

    Additional info can be found at this post about Ruby Classes.

提交回复
热议问题