试图理解Ruby中self.method_name与Classname.method_name的使用

我试图了解何时使用self.method_name与何时使用Classname.method_name。

在下面的示例中,为什么“before_create”需要引用“User.hash_password”而不是“self.hash_password”或只是“hash_password”?

由于我们已经在User类中,我认为before_create方法将“知道”“hash_password”是其自己的类的成员,并且不需要任何特殊语法来引用它。

require 'digest/sha1' class User  ["name = ? and hashed_password = ?", name, hashed_password]) end def try_to_login User.login(self.name, self.password) end private def self.hash_password(password) Digest::SHA1.hexdigest(password) end end 

 def before_create self.hashed_password = User.hash_password(self.password) end 

在此示例中, User.hash_password User上调用hash_password方法,而self.hashed_password=此特定 User 实例上调用hashed_password=方法。

如果用self.hash_password替换User.hash_password ,Ruby会抱怨NoMethodError ,因为类User存在hash_password名称的实例方法。 不过,你可以用self.class.hash_password替换它。

如果用hashed_password=替换self.hashed_password= ,Ruby会创建一个名为hashed_password的局部变量,而不是调用实例方法hashed_password= 。 如果要调用属性编写器,则需要显式添加self

方法定义中的selfdef self.hash_password )使hash_password成为类方法而不是实例方法。 在这种情况下, self指的是阶级 。 在实例方法的上下文中, self指的是实例

您要问的是类方法和实例方法之间的区别。

有几种方法可以定义类方法:

 class Klass def Klass.method_name .. end end 

这跟做的一样:

 class Klass def self.method_name .. end end 

或者首选的ruby成语:

 class Klass class << self def method_name .. end end end 

如果Klass已经宣布你也可以做..

 def Klass.method_name .. end 

要么:

 class << Klass def method_name .. end end 

或者你甚至可以使用Module #extend:

 Klass.extend(Module.new { def method_name; puts 'ducky'; end }) 

就像你将一个单例方法添加到一个对象。 实际上,类方法是在类级别上操作的单例方法。

例如,在rails ActiveRecord中你有一个类方法'find',你可以在任何Model上使用它:

 Person.find(1) 

以及对单个对象进行操作的“保存”等实例方法

 person = Person.find(1) ... person.save 

在我正在进行的当前项目中,我有一个包含数据馈送的模型Feed。 我需要定期运行一个更新所有feed的方法,这样我就有了一个fetch_all方法来完成这个。

 class Feed < ActiveRecord::Base // class method Feed.fetch_all def self.fetch_all Feed.all.each do |feed| feed.fetch_value end end // instance method def fetch_value // grabs updated value and saves end end 

我还没有深入研究Ruby,但是根据你的描述,我会说hash_password是一个静态方法,或者能够以静态方式使用。