When to use self.class.function vs self.function

Hi Guys,

I'm experimenting with my first rails app currently. One thing I'm
trying to implement is a login system.

I created a model for user.rb I've added a couple of functions to the
class for example:

def self.authenticate(user_info)
   find_by_username_and_password(....,
self.hashed_password(user_info[:password]))
end

def self.hashed_password(password)
  Digest::SHA2.hexdigest(password)
end

So from user.rb function self.authenticate I can call
self.hashed_password and it works fine.

From another file (user_controller.rb) I try to create a new user
based on the authentication parameters, and then call authenticate on
that user. In order to do that I have to call
user_into.class.authenticate instead of user_info.authenticate...

I don't understand what is going on here with def self.{function} and
the .class modifier.

Can someone point to me somewhere to explain? I have a feeling I'm
doing something wrong but I don't understand what.

Thanks

Hi Guys,

I'm experimenting with my first rails app currently. One thing I'm
trying to implement is a login system.

I created a model for user.rb I've added a couple of functions to the
class for example:

def self.authenticate(user_info)
find_by_username_and_password(....,
self.hashed_password(user_info[:password]))
end

def self.hashed_password(password)
Digest::SHA2.hexdigest(password)
end

So from user.rb function self.authenticate I can call
self.hashed_password and it works fine.

From another file (user_controller.rb) I try to create a new user
based on the authentication parameters, and then call authenticate on
that user. In order to do that I have to call
user_into.class.authenticate instead of user_info.authenticate...

I don't understand what is going on here with def self.{function} and
the .class modifier.

Can someone point to me somewhere to explain? I have a feeling I'm
doing something wrong but I don't understand what.

In the context of a class def self.foo creates a class methods (more
generally it is used to create singleton methods).

Calling foo or self.foo tries to call a foo method on the current
object - it won't call a class method if you're currently in an
instance method, because self is an actual user. You can call class
methods by writing User.foo, rather than writing User.foo, you can
instead write self.class.foo (assuming that self.class is User) - it's
a little more explicit and neater too (eg if the code is inside a
module that could be included in many models etc...). Once you're
inside a class method like authenticate then self is the class so you
can write self.hashed_password or even just hashed_password
(self.class.hashed_password would try to call the method on Class
itself, which wouldn't work)

Fred

Fred

Fred

Hi pipplo,

When you define a "def self.function" method in yor User class, you
define a "class level" method.
When you define a "def function" method, you define an "instance level
method".

Class and instance level define from where you can call a method:
If its class level you need a class and thats why you call it as
"User.authenticate". Given an object it needs a .class after it to
obtain its class.
On the other hand instance level means your method is callable from an
object, so you call it as "my_user.name". Also, since you need a
particular object of a class, you can't call "User.name".

"self" references to the object that called the method:
If you use self when defining a method, self references to the class
you are defining it for.
If you use self into a method's code defined at class level ( def
self.method), again it references to the class (a class is also an
object itself).
If you use self into a method's code defined at instance level, it
references to the particular object that called the method. For
instance: if you call "my_user.method", "self" inside "method" would
reference "my_user".

Awesome!

Thanks Fred and Xuan. I was able to really clean up my code once I
understood this.

One side question based on this. Is there some normal ruby coding
guidelines? I was thinking I would want to make class level functions
capital, and instance level functions lowercase.

User.Authenticate
user.hash_password

I'll keep looking. Thanks everyone again.

Joe

Ruby guidelines state that methods should always be lowercase, just as
your second example. Capitals should be used to name classes.