Why should we bother to separate our code in classes? After all, we could just put lots of methods into the top-level scope and then just have them available all throughout an application.
By this point, we know this approach isn't a good idea. Global variables are generally bad. Variables and methods should be as tightly scoped as possible. In other words, they should only be made available to parts of the application where they are needed. If possible, methods should be used and attributes updated only in the class where they are defined.
The process of separating code out and making it available only in a single class is called encapsulation. There are a number of ways to do this in Ruby. For instance, we should always think carefully about whether an attribute should have reader and writer methods. We could easily add both to every attribute but this would be a sign of poorly-encapsulated code.
We can also make methods private, which means they can only be called inside the class where they are defined. We use the
private keyword to denote which methods should be private. Here's an example:
class Car def start puts "car started!" inject_fuel() end private def inject_fuel puts "fuel injected!" end end
Car class above, we have two methods. The
start() method can be called outside the
Car class. However, the
inject_fuel() method can only be called inside the class. Let's open IRB to demonstrate what happens if we try to call both of these methods:
> car = Car.new() > car.inject_fuel NoMethodError: private method 'inject_fuel' called for #<Car:0x007facd880ea08> > car.start car started! fuel injected!
We'll get a
NoMethodError: private method 'inject_fuel' error if we try to call our private method. However, if we call the
start() method, it can successfully call the
inject_fuel() method because it is calling the method within the class. Our
inject_fuel() method has successfully been encapsulated.
You are not expected to use the
private keyword for this section's independent project. However, you're encouraged to encapsulate code where possible and to experiment with
private methods. There are a few important points regarding
Any methods declared beneath the
private keyword will be
Private methods can only be called on
self implicitly. This is a bit of a tricky concept. Let's clarify what this means with another example. Let's say we update the
start() method above to look like this:
def start puts "car started!" self.inject_fuel() end
It will no longer work. This is because we've called
inject_fuel() explicitly on
self. We can't explicitly call
inject_fuel() on self or any other variable, even if that variable happens to be an instance of
Car. It can only be called implicitly on
self, which is what happens when we call the method by itself
self is only available implicitly within the class so it makes sense that a
private method can only be called implicitly.
Encapsulating classes is considered the best, most professional practice for several reasons:
It allows a class to have more control over its attributes and methods, which is more secure.
It prevents other classes from accessing and altering attributes and methods, which can lead to difficult bugs.
While we may not see this benefit until our applications become larger, encapsulation leads to more maintainable code.
Managing all aspects of a class within the class itself leads to more organized code. Organized code allows other developers to comprehend, collaborate, and implement your logic much more easily.
private methods in your own code and endeavor to make your code as well-encapsulated as possible.
Encapsulation: The process of limiting access to fields so they are available only to a limited part of an application such as a class. It's a best practice because:
Private method: A method that can only be called inside the class where it is defined.
privatekeyword in a class.
selfand can't be called in any other way.
Lesson 14 of 22
Last updated August 7, 2022