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.