When should we consider using private or protected? - ruby-on-rails

Just wondering, when should we actually must use private or protected for some methods in the model?
Sometimes I can't not be bothered to group my methods in private nor protected. I just leave it as it is. But I know it must be a bad practice, otherwise these 2 groupings won't be created in programming.
Thanks.

If you plan to call a method externally, record.method(), then "public"
If it will be used only internally, self.method(), then "private"
If you plan to use it internally, but also in descendants, self.method() # in subclass, then "protected"

I'll give my opinion, and maybe I'll get a kicking for it, but I don't bother with protected or private in Ruby. The reality is, Ruby treats you like an adult, if you want to run a private method from outside the class, you can (there are ways). You can run protected methods outside the class. You can even reassign constants... you can do whatever you like, basically.
And that's why I like it, it's your responsibility. My feeling is, that to mark something as protected or private you are doing two things:
Indicating that you don't think a consumer will need it.
Second guessing what someone else needs.
and in addition, you're making it harder to test, as it can be a real pain testing private methods (see What's the best way to unit test protected & private methods in Ruby? for ways around it)
For those last two reasons, I don't bother with them. If you really wanted some kind of barrier between your classes/methods and the consumers (be they code or developers) then there are other, more effective ways (proxies, obfuscation, encryption, password protected methods etc). Otherwise, why not give them access to the same tools you used?

I don't know Ruby as a special case, but I assume the answer would be the same as for other languages too, so here it is:
A private method can only be accessed by members of the same class, whereas a protected is also available for member of classes that extend the base class where the method is declared.

Related

Creating and storing generic methods in ruby on rails

I'm making a method inside a Ruby on Rails app called "print" that can take any string and converts it into a png. I've been told it's not good to make class methods for base ruby classes like String or Array or Hash, etc. so "some string to print".print is probably not something I should do.
I was thinking about making a subclass of String called Print (class Print < String) and storing it in my lib/assets folder. So it would look like: Print.new("some string to print"). So my question is, am I on the right track by 1) creating a sub-class from String and 2) storing it in lib/assets?
Any guidance would be greatly appreciated!
Answers to your question will necessarily be subjective because there are always be many answers to "where should I put functionality?", according to preference, principle, habit, customs, etc. I'll list a few and describe them, maybe add some of my personal opinions, but you'll ultimately have to choose and accept the consequences.
Note: I'll commonly refer to the common degenerate case of "losing namespacing scope" or "as bad as having global methods".
Monkeypatch/Extend String
Convenient and very "OO-message-passing" style at the cost of globally affecting all String in your application. That cost can be large because doing so breaks an implicit boundary between Ruby core and your application and it also scatters a component of "your application" in an external place. The functionality will have global scope and at worst will unintentionally interact with other things it shouldn't.
Worthy mention: Ruby has a Refinements feature that allows you to do do "scoped monkeypatching".
Worthy mention 2: Ruby also lets you includes modules into existing classes, like String.class_eval { include MyCustomization } which is slightly better because it's easier to tell a customization has been made and where it was introduced: "foo".method(:custom_method).owner will reveal it. Normal Monkeypatching will make it as if the method was defined on String itself.
Utils Module
Commonly done in all programming languages, a Util module is simply a single namespace where class methods/static methods are dumped. This is always an option to avoid the global pollution, but if Util ends up getting used everywhere anyways and it gets filled to the brim with unrelated methods, then the value of namespacing is lost. Having a method in a Util module tends to signify not enough thought was put into organizing code, since without maintenance, at it's worst, it's not much better than having global methods.
Private Method
Suppose you only need it in one class -- then it's easy to just put it into one private method. What if you need it in many classes? Should you make it a private method in a base class? If the functionality is inherent to the class, something associated with the class's identity, then Yes. Used correctly, the fact that this message exists is made invisible to components outside of that class.
However, this has the same downfall as the Rails Helper module when used incorrectly. If the next added feature requires that functionality, you'll be tempted to add the new feature to the class in order to have access to it. In this way the class's scope grows over time, eventually becoming near-global in your application.
Helper Module
Many Rails devs would suggest to put almost all of these utility methods inside rails Helper modules. Helper modules are kind of in between Utils Module and Private Method options. Helpers are included and have access to private members like Private Methods, and they suggest independence like Utils Modules (but do not guarantee it). Because of these properties, they tend to end up appearing everywhere, losing namespacing, and they end up accessing each other's private members, losing independence. This means it's more powerful, but can easily become much worse than either free-standing class/static methods or private methods.
Create a Class
If all the cases above degenerate into a "global scope", what if we forcibly create a new, smaller scope by way of a new class? The new class's purpose will be only to take data in and transform it on request on the way out. This is the common wisdom of "creating many, small classes", as small classes will have smaller scopes and will be easier to handle.
Unfortunately, taking this strategy too far will result in having too many tiny components, each of which do almost nothing useful by themselves. You avoid the ball of mud, but you end up with a chunky soup where every tiny thing is connected to every other tiny thing. It's just as complicated as having global methods all interconnected with each other, and you're not much better off.
Meta-Option: Refactor
Given the options above all have the same degenerate case, you may think there's no hope and everything will always eventually become horribly global -- Not True! It's important to understand they all degenerate in different ways.
Perhaps functionality 1, 2, 3, 4... 20 as Util methods are a complete mess, but they work cohesively as functionality A.1 ~ A.20 within the single class A. Perhaps class B is a complete mess and works better broken apart into one Util method and two private methods in class C.
Your lofty goal as an engineer will be to organize your application in a configuration that avoids all these degenerate cases for every bit of functionality in the system, making the system as a whole only as complex as necessary.
My advice
I don't have full context of your domain, and you probably won't be able to communicate that easily in a SO question anyways, so I can't be certain what'll work best for you.
However, I'll point out that it's generally easier to combine things than it is to break them apart. I generally advise starting with class/static methods. Put it in Util and move it to a better namespace later (Printer?). Perhaps in the future you'll discover many of these individual methods frequently operate on the same inputs, passing the same data back and forth between them -- this may be a good candidate for a class. This is often easier than starting off with a class or inheriting other class and trying to break functionality apart, later.

Encapsulation - Why I am using getter setter to make my data members public if I already declare them private in class

I just want to ask, we are having one class, in which we have two private data members say:
class Employee{
private int empid;
private String empname;
}
I am declaring them private that means I can use them in Employee class only. So what is the need to create getter setter for both the data members and making them public.
Hope you got my problem.
This is an excellent question. Often you see code examples that make members private but exposing them via a getter/setter pair, without the getter/setter doing anything else than setting the corresponding member.
In my book this is not encapsulation at all. You are no better of than just making the members public. Although a lot of people are uneasy to do that, they would happily provide accessors automatically for all their members.
One reason to do provide accessors is the ability to do input validation. E.g. if you empIds have a checksum, you could enforce it in the setter. Something that is not possible with direct access to the member.
In my opinion it would be better to think about the role this object will play and see how it can achieve that role with a minimum of accessors. Otherwise your code will probably violate the Law of Demeter.
You are absolutely right, that creating a setter/getter or making the fields public both violate encapsulation in the same way, therefore if you do want to encapsulate your private fields, presumably because you are working in an Object-Oriented environment, you do not want to use either of those things.
To your question why there is a need to have create setter/getters: Most projects (consciously or unconsciously) do not base their designs on Object-Orientation. There are other paradigms, where data and function are separated, thus encapsulation plays a minor role if any.
In the Java world it is common to have pure (or very close to pure) data structures (Beans), and Services/Components/EJBs/etc that work on these Beans (have access to all fields basically). Often these architectures split the function part further into topics like Presentation, Business, Persistence (3-tier architectures), or create explicit control procedures that has access to all the relevant fields (like how MVC is often done).
Whether one approach is better than the other would be a subjective discussion probably, but the short answer is: It's a different paradigm usually (not OO), that is why setters/getters get created.

Unit testing private method - objective C

I use GHUnit. I want to unit test private methods and don't know how to test them. I found a lot of answers on why to or why not to test private methods. But did not find on how to test them.
I would not like to discuss whether I should test privates or not but will focus on how to test it.
Can anybody give me an example of how to test private method?
Methods in Objective-C are not really private. The error message you are getting is that the compiler can't verify that the method you are calling exists as it is not declared in the public interface.
The way to get around this is to expose the private methods in a class category, which tells the compiler that the methods exist.
So add something like this to the top of your test case file:
#interface SUTClass (Testing)
- (void)somePrivateMethodInYourClass;
#end
SUTClass is the actual name of the class you are writing tests for.
This will make your private method visible, and you can test it without the compiler warnings.
A little late, but I just got onto the TDD train.
Private methods shouldn't be tested. Because you write private methods to support your public methods, thus testing your public methods indirectly tests the private methods which support them.
The principle "private methods shouldn't be tested" is supported by the principle "when you need to test private methods, it probably means that you should move those methods to the separate class", thus making them public.
If a method is private, you never should test it.
Think about this. You should test behaviour and contract of your methods instead internal implementation
Agreed with #Lord Zsolt
Also please note next (from Test-Driven iOS Development ISBN-10: 0-321-77418-3, ISBN-13: 978-0-321-77418-7 )
Testing Private Methods
I have often been asked, “Should I test my
private methods?” or the related question “How should I test my
private methods?” People asking the second question have assumed that
the answer to the first is “Yes” and are now looking for a way to
expose their classes’ pri- vate interfaces in their test suites.
My answer relies on observation of a subtle fact: You already have tested
your private meth- ods. By following the red–green–refactor approach
common in test-driven development, you designed your objects’ public
APIs to do the work those objects need to do. With that work specified
by the tests—and the continued execution of the tests assuring you
that you haven’t broken anything—you are free to organize the internal
plumbing of your classes as you see fit. Your private methods are
already tested because all you’re doing is refactoring behavior that
you already have tests for.
You should never end up in a situation
where a private method is untested or incompletely tested, because you
create them only when you see an opportunity to clean up the
implementation of public methods. This ensures that the pri- vate
methods exist only to support the class’s public behavior, and that
they must be invoked during testing because they are definitely being
called from public methods.

Rails: what are the main reasons for making methods private?

If the end_user cannot access the source code of the app, why we still need to make some methods private?
I'm reading the Pragmatic Agile Web Development with Rails and I couldn't understand why we need to make the following method private (even after reading the explanation):
private
def current_cart Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
end
It says that it will never allow Rails to make it available as an action, but as a coder, why would I ever do that myself?
As you say there may be no external reason to make it private. However, it also prevents you — or somebody else using your code — from accidentally making use of the method where you're not supposed to.
See it as a sanity check on your own future behaviour if you will.
It aims to encourage good practices and good code.
The idea is that you have two separate parts to your code:
"Above the line" (Public). This is the interface to the rest of the world. This is the API, where calls are made when using instances of the object. Once created, you know that THIS is the area where changes can affect current usages of the code.
"Below the line (Private). This is where detailed logic resides. This code can be changed and refactored freely without any affect to the public interface.
It may help guide your test writing
Private methods may or may not be (unit) tested.
Public methods are more encouraging of both unit and integrated tests as the fact that is is public means that it is serving as the public face for that code and as it is public it might be called from any other point in the future, so having good tests to make sure it continues to work as advertised is essential.
It may help with security as you have greater control who calls private methods (i.e. only public methods in the same class calling them).
It may help reduce name collisions as you have less names in the public space.
End user might not be able to access your code but someone else in your team can definitely access it and they might change it.
The other benefit of encapsulation is that it allows one class ("server") to make a contract with another class ("client") to provide some service with only a very few things being required to be known about the "server" class such as method signature and return type. The benefit is only realized if the contract of what is required and what is returned remains the same. So, in your example, there is no benefit since the contract was broken by Class A.
Instead of class A changing int type to float, class A should create another new variable of type float for other classes to use so that class B is not "broken" or that contract is not broken between them. Class C could refer to new float variable and Class B could still refer to old int variable and everyone is happy. Better yet, methods would used to retrieve values such as: "getUsersAddress" and "getUSersPhoneNumber" depending on what was wanted.
The real benefit of good encapsulation is that Class A can be completely re-written from top to bottom and as long as the contract is honored as to what Class A is expected to do(have methods "getUsersAddress" and "getUSersPhoneNumber"), then everything in Class B and C works the same. Think carefully about what is exposed and how it is exposed. Things that will change often and break other classes need to be considered carefully before exposing. Good encapsulation means hiding things that are expected to change often so to avoid breaking other classes.
It says that it will never allow Rails to make it available as an action,
Hmm, is this in a Rails Conroller class? And is the book you are working through written for Rails 2.x?
In Rails 2.x, by default any public method in a Controller can be triggered by someone accessing the url /name_of_controller/name_of_method .
But there are some methods in your controller that you don't want anyone on the web to trigger, they weren't intended as 'action methods'. So in Rails 2.x, you mark those as protected or private, something not public. "action method" means a method you intend to be directly triggered via a URL.
In Rails 3.x, routing has generally changed such that only certain methods you explicitly route to are available to be triggered via a URL. However, it might still make sense to mark non-action-methods in a Controller as protected or private so:
It's more clear from skimming the source which methods are action methods and which aren't
As a precaution in case someone changes the routing in such a way that would allow a URL to trigger those methods not intended as action methods
Or for general reasons of code organization that other answers mention, that are not specific to Rails controller classes.
There are several reasons as mentioned above. The interesting thing about this encapsulation in ruby is that it can be violated.
See the "send" method and its brother "public_send".
And for a very common metaprogramming technique that uses this method see:
dynamic finders

A pragmatic view on private vs public

I've always wondered on the topic of public, protected and private properties. My memory can easily recall times when I had to hack somebody's code, and having the hacked-upon class variables declared as private was always upsetting.
Also, there were (more) times I've written a class myself, and had never recognized any potential gain of privatizing the property. I should note here that using public vars is not in my habit: I adhere to the principles of OOP by utilizing getters and setters.
So, what's the whole point in these restrictions?
The use of private and public is called Encapsulation. It is the simple insight that a software package (class or module) needs an inside and an outside.
The outside (public) is your contract with the rest of the world. You should try to keep it simple, coherent, obvious, foolproof and, very important, stable.
If you are interested in good software design the rule simply is: make all data private, and make methods only public when they need to be.
The principle for hiding the data is that the sum of all fields in a class define the objects state. For a well written class, each object should be responsible for keeping a valid state. If part of the state is public, the class can never give such guarantees.
A small example, suppose we have:
class MyDate
{
public int y, m, d;
public void AdvanceDays(int n) { ... } // complicated month/year overflow
// other utility methods
};
You cannot prevent a user of the class to ignore AdvanceDays() and simply do:
date.d = date.d + 1; // next day
But if you make y, m, d private and test all your MyDate methods, you can guarantee that there will only be valid dates in the system.
The whole point is to use private and protected to prevent exposing internal details of your class, so that other classes only have access to the public "interfaces" provided by your class. This can be worthwhile if done properly.
I agree that private can be a real pain, especially if you are extending classes from a library. Awhile back I had to extend various classes from the Piccolo.NET framework and it was refreshing that they had declared everything I needed as protected instead of private, so I was able to extend everything I needed without having to copy their code and/or modify the library. An important take-away lesson from that is if you are writing code for a library or other "re-usable" component, that you really should think twice before declaring anything private.
The keyword private shouldn't be used to privatize a property that you want to expose, but to protect the internal code of your class. I found them very helpful because they help you to define the portions of your code that must be hidden from those that can be accessible to everyone.
One example that comes to my mind is when you need to do some sort of adjustment or checking before setting/getting the value of a private member. Therefore you'd create a public setter/getter with some logic (check if something is null or any other calculations) instead of accessing the private variable directly and always having to handle that logic in your code. It helps with code contracts and what is expected.
Another example is helper functions. You might break down some of your bigger logic into smaller functions, but that doesn't mean you want to everyone to see and use these helper functions, you only want them to access your main API functions.
In other words, you want to hide some of the internals in your code from the interface.
See some videos on APIs, such as this Google talk.
Having recently had the extreme luxury of being able to design and implement an object system from scratch, I took the policy of forcing all variables to be (equivalent to) protected. My goal was to encourage users to always treat the variables as part of the implementation and not the specification. OTOH, I also left in hooks to allow code to break this restriction as there remain reasons to not follow it (e.g., the object serialization engine cannot follow the rules).
Note that my classes did not need to enforce security; the language had other mechanisms for that.
In my opinion the most important reason for use private members is hiding implementation, so that it can changed in the future without changing descendants.
Some languages - Smalltalk, for instance - don't have visibility modifiers at all.
In Smalltalk's case, all instance variables are always private and all methods are always public. A developer indicates that a method's "private" - something that might change, or a helper method that doesn't make much sense on its own - by putting the method in the "private" protocol.
Users of a class can then see that they should think twice about sending a message marked private to that class, but still have the freedom to make use of the method.
(Note: "properties" in Smalltalk are simply getter and setter methods.)
I personally rarely make use of protected members. I usually favor composition, the decorator pattern or the strategy pattern. There are very few cases in which I trust a subclass(ing programmer) to handle protected variables correctly. Sometimes I have protected methods to explicitly offer an interface specifically for subclasses, but these cases are actually rare.
Most of the time I have an absract base class with only public pure virtuals (talking C++ now), and implementing classes implement these. Sometimes they add some special initialization methods or other specific features, but the rest is private.
First of all 'properties' could refer to different things in different languages. For example, in Java you would be meaning instance variables, whilst C# has a distinction between the two.
I'm going to assume you mean instance variables since you mention getters/setters.
The reason as others have mentioned is Encapsulation. And what does Encapsulation buy us?
Flexibility
When things have to change (and they usually do), we are much less likely to break the build by properly encapsulating properties.
For example we may decide to make a change like:
int getFoo()
{
return foo;
}
int getFoo()
{
return bar + baz;
}
If we had not encapsulated 'foo' to begin with, then we'd have much more code to change. (than this one line)
Another reason to encapsulate a property, is to provide a way of bullet-proofing our code:
void setFoo(int val)
{
if(foo < 0)
throw MyException(); // or silently ignore
foo = val;
}
This is also handy as we can set a breakpoint in the mutator, so that we can break whenever something tries to modify our data.
If our property was public, then we could not do any of this!

Resources