Hello I was reviewing some rails code lately and I see that in some cases they use private methods (especially in application controller methods). I understand that it is considered a good practice since the methods aren't used anywhere else outside of application controller, but my question is: What would happened if you never use private methods? Will it be some security issue (and if yes, I'd like to see an example if it is possible), is it just a good practice just to use methods inside the scope of the class that it's been used or is there any gains in resources because there is narrower scope? It might sound pretty newbie question but I am fairly new to OOP and I'd like some guidance in this topics (even from some book or resource about stuff like that). Thank you (I show a debate lately if there are any real advantages of OOP over procedural programming and if OOP is just a myth and I am thinking this a lot lately, so I decided to learn more about OOP and decide for myself... I was also wondering if ruby and rails could be done with procedural programming, instead of classes use functions and what it couldn't be done so easily).
on 2010-05-24 12:15
on 2010-05-24 12:39
> > What would happened if you never use private methods? Will it be some > security issue (and if yes, I'd like to see an example if it is > possible) OK, here's a quick example. Assuming you have the default routing rules in place so it handles /:controller/:action class LoginsController < ApplicationController def create @user = User.login(params) if @user.admin? set_as_admin else set_as_normal end end def set_as_admin session[:user_type] = :admin session[:user_id] = @user.id end def set_as_normal session[:user_type] = :normal session[:user_id] = @user.id end end So you login with normal/password and it runs the internal method "set_as_normal" to store the details in the session. You then visit http://www.example.com/logins/set_as_admin and BOOM! You're now an administrator. This wouldn't be possible if you put "private" above "def set_as_admin". It's a fairly simple example, and I wouldn't code logins like that, but it shows that without declaring methods as private in controllers it gives the user an easy way to access them. Just for completeness, the easiest protection for this in the real world is to 1) disable the default routing, 2)don't use two methods for set_as_* - use one and do the admin? check in that method. However, it was a simple example off the top of my head as to why use private in a controller. Cheers, Andy
on 2010-05-24 13:41
You opened my eyes! I haven't figured out what private was. I thought that you could access the method logins/set_as_admin even if it was private because I thought by /logins/ you have access to the class, that's what I understood before when I read that private methods could accessed by the class itself and only. So, private methods can be accessed only by public methods of the class, right? I wonder what protected is but I will search it and try some examples. Thanks again :)
on 2010-05-24 13:55
Private and protected methods can both be called from the same class or a subclass (eg your controller classes typically inherit from ApplicationController, your model classes typically inherit from ActiveRecord::Base, etc). This is different from the conventions used in many other languages like Java and C. Private methods can only be called from the same instance of an object. In the case of ApplicationController there will only be one instance so it doesn't matter but if you had a private method defined in a model class this would come into play. A private method cannot be called from any object except that object itself (the same instance). Protected methods can be called from an instance of the same class or subclass. So two instances of the same class can call each others' protected methods but not each others' private methods. Hope this helps! - Matt