Home  >  Q&A  >  body text

Ruby的class中定义以self.开头的方法有何不同

比如这个代码

class Category < ActiveRecord::Base
...

  def self.last_updated_at
    order('updated_at desc').limit(1).pluck(:updated_at).first.to_i
  end

...
end

为什么不直接定义last_updated_at方法呢?

高洛峰高洛峰2712 days ago615

reply all(3)I'll reply

  • PHP中文网

    PHP中文网2017-04-22 09:01:47

    self 指向当前 class,所以这种定义方法会定义出 class 方法(class method),如果不加 self. will define the instance method.

    This way of writing self. is equivalent to:

    in your example
      def Category.last_updated_at
        ...
      end
    

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-22 09:01:47

    There are two types of methods that a ruby ​​object can call.
    One type is defined in the class of the object, called instance method, such as

    def last_updated_at
        #blahblah
    end
    

    Then the instance of Category can call this method, but the Category itself cannot

    category1=Category.new
    category2=Category.new
    category1.last_updated_at    #legal
    category2.last_updated_at    #legal
    Category.last_updated_at    #illegal
    

    The other type is called singleton method, which can only be called by one object, not the class of the object, nor other objects belonging to the same class as the object. The singleton method is defined as follows

    #category1=Category.new
    def category1.last_updated_at
        #blahblah
    end
    

    After this definition, only the category1 object can call the last_updated_at method

    category1.last_updated_at    #legal
    category2=Category.new
    category2.last_updated_at    #illegal
    Category.last_updated_at    #illegal
    

    Ruby classes are also objects, and they can also define their own singleton methods, such as

    def Category.last_udpated_at
        #blahblah
    end
    

    In this way, only Category can call the last_updated_at method, but not its instances, nor other classes, nor any other objects to be exact

    Category.last_updated_at    #legal
    category=Category.new
    category.last_updated_at    #illegal
    

    Inside the definition of the Category class (outside the method), self refers to the Category itself, so

    def Category.last_udpated_at
        #blahblah
    end
    

    can be replaced by

    def self.last_udpated_at
        #blahblah
    end
    

    This is the method defined in your question. Do you understand now? In essence, it is the singleton method of Category, and Category is a class. The singleton method of a class is also called the class method of the class and can only be called by the class itself.

    It should be noted that a class method is a singleton method, but it is a singleton method of a class. Other than that, there is nothing special about it. Just like the instance method is held by the class to which the object belongs, the singleton method is also held by something called the eigenclass of the object. There is a lot more knowledge about eigenclass, so I won’t mention it here. I will talk about it in the article.

    reply
    0
  • 迷茫

    迷茫2017-04-22 09:01:47

    Add self to define a class method, otherwise it is an instance method

    Define class methods can also be

    class << self
        def last_updated_at
        order('updated_at desc').limit(1).pluck(:updated_at).first.to_i
      end
    end
    

    reply
    0
  • Cancelreply