试图理解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
。
方法定义中的self
( def 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是一个静态方法,或者能够以静态方式使用。