I'm trying to understand when to use self.method_name vs. when to use Classname.method_name.
In the example below, why does "before_create" need to reference "User.hash_password" instead of "self.hash_password" or just "hash_password"?
Since we are in the User class already, I thought the before_create method would "know" that "hash_password" is a member of its own class and would not need any special syntax to refer to it.
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
self is a special variable that points to the object that "owns" the currently executing code. Ruby uses self everwhere: For instance variables: @myvar. For method and constant lookup.
the method self refers to the object it belongs to. Class definitions are objects too. If you use self inside class definition it refers to the object of class definition (to the class) if you call it inside class method it refers to the class again.
def before_create
self.hashed_password = User.hash_password(self.password)
end
In this example, User.hash_password
calls the hash_password
method on the class User
, whereas self.hashed_password=
calls the hashed_password=
method on this particular instance of User
.
If you replace User.hash_password
with self.hash_password
, Ruby would complain with a NoMethodError
, because no instance method by the name of hash_password
exists in the class User
. You could replace it with self.class.hash_password
, though.
If you replace self.hashed_password=
with simply hashed_password=
, Ruby would create a local variable named hashed_password
, rather than call the instance method hashed_password=
. You need to explicitly add self
if you want to call attribute writers.
The self
in the method definition (def self.hash_password
) makes hash_password
a class method instead of an instance method. In this context, self
refers to the class. In the context of an instance method, self
refers to an instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With