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 -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2010-Sep-06 07:41 UTC
Re: When to use self.class.function vs self.function
On Sep 6, 7:00 am, pipplo <joe.kos...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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> Thanks-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 6 sep, 08:00, pipplo <joe.kos...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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. > > ThanksHi 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". -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
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 On Sep 6, 10:01 am, Xuan <xua...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 6 sep, 08:00, pipplo <joe.kos...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > 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 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".-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Ruby guidelines state that methods should always be lowercase, just as your second example. Capitals should be used to name classes. On 6 sep, 19:59, pipplo <joe.kos...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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 > On Sep 6, 10:01 am, Xuan <xua...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > On 6 sep, 08:00, pipplo <joe.kos...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > 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 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".-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.