Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand use of self.method_name vs. Classname.method_name in Ruby

Tags:

ruby

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
like image 204
pez_dispenser Avatar asked May 14 '09 14:05

pez_dispenser


People also ask

What is the use of self in Ruby?

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.

What does self refer to in an instance method body?

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.


1 Answers

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.

like image 85
molf Avatar answered Oct 22 '22 19:10

molf