我试图了解何时使用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 < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :password
validates_presence_of :name, :password
validates_uniqueness_of :name
def before_create
self.hashed_password = User.hash_password(self.password)
end
def after_create
@password = nil
end
def self.login(name, password)
hashed_password = hash_password(password || "")
self.find(:first, :conditions => ["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
Run Code Online (Sandbox Code Playgroud)
mol*_*olf 13
def before_create
self.hashed_password = User.hash_password(self.password)
end
Run Code Online (Sandbox Code Playgroud)
在此示例中,User.hash_password调用hash_password该方法的类 User,而self.hashed_password=调用hashed_password=上方法此特定实例的User.
如果替换User.hash_password为self.hash_password,Ruby会抱怨NoMethodError,因为类中没有名称hash_password存在的实例方法User.不过你可以用它替换它self.class.hash_password.
如果self.hashed_password=简单地替换hashed_password=,Ruby将创建一个名为的局部变量hashed_password,而不是调用实例方法hashed_password=.self如果要调用属性编写器,则需要显式添加.
所述self的方法中定义(def self.hash_password)使hash_password一个类的方法,而不是一个实例方法.在这种情况下,self指的是类.在实例方法的上下文中,self指的是一个实例.
Cor*_*ook 12
您要问的是类方法和实例方法之间的区别.
有几种方法可以定义类方法:
class Klass
def Klass.method_name
..
end
end
Run Code Online (Sandbox Code Playgroud)
这跟做的一样:
class Klass
def self.method_name
..
end
end
Run Code Online (Sandbox Code Playgroud)
或者首选的红宝石成语:
class Klass
class << self
def method_name
..
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果Klass已经宣布你也可以做..
def Klass.method_name
..
end
Run Code Online (Sandbox Code Playgroud)
要么:
class << Klass
def method_name
..
end
end
Run Code Online (Sandbox Code Playgroud)
或者你甚至可以使用Module #extend:
Klass.extend(Module.new { def method_name; puts 'ducky'; end })
Run Code Online (Sandbox Code Playgroud)
就像你会向对象添加单例方法一样.实际上,类方法是在类级别上操作的单例方法.
例如,在rails ActiveRecord中你有一个类方法'find',你可以在任何Model上使用它:
Person.find(1)
Run Code Online (Sandbox Code Playgroud)
和'save'这样的实例方法,它们对单个对象进行操作
person = Person.find(1)
...
person.save
Run Code Online (Sandbox Code Playgroud)
在我正在处理的当前项目中,我有一个包含数据馈送的模型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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3125 次 |
| 最近记录: |