Homepage

Do You Really Know Public Private And Protected In Ruby

Public, protected and private access – all of the programmers are familiar with that concept. Nothing special, we work with them on a daily basis. However, as Ruby developers, do we really know the details? Read on and challenge yourself!

Public, private and protected access - all of the programmers are familiar with that concept. Nothing special, we work with them on a daily basis. However, as Ruby programmers, do we really know the details?

You can check yourself with these five statements. Try to answer: TRUE or FALSE.

Statements:

  1. Public methods have no access control - they can be called from the outside of the class definition by the instance of that class or it's subclasses

  2. Both protected and private methods cannot be called from the outside of the defining class

  3. Protected methods are accessible from the subclass and private methods are not

  4. Private methods of the defining class can be invoked by any instance of that class

  5. Public access is the default one

We will back to the correct answers at the end of this article. For now let’s go deeper into some nuances of public, private and protected access control. To make it more practical I prepared sample code to play with. I recommend cloning this repo to make continuing with the article easier. It’s just one file. If you would like to think of the solution first, then hold off running the code.

Here is the sample code:

ruby

You can see the base class Region here along with two child classes: Country and City. City and Country inherit from Region. Inheritance is used to demonstrate the public, private and protected details. At the end of the file, we can find initialization part and 4 sections which we’ll discuss below. Take a look at the file to get familiar with the code.

Ok, let’s start! In the 3rd section of the initialization, the following objects are created - wroclaw, san_francisco and poland. These objects will be used for demonstration purposes in the upcoming sections. I suggest treating all these segments separately. You can comment out the particular section before you go to the next one. In that way, errors won’t block the rest of the output.

I Section

Topic: Public access.

In the first section greeting method is invoked twice: by the wroclaw and by the poland objects. Nothing special here. Public access is straightforward. The greeting is accessible for its class’s object (`poland`) and for its child-class’s object (`wroclaw`).

ruby

Conclusion: Public access is evident and intuitive. There are no restrictions. Also, it is the default access modifier.

II Section

Topic: Access to the private and protected methods from the outside of the defining class.

There are two important methods in that section: protected name_info and private population_info. The result seems to be intuitive again. wroclaw object has no access to neither the private methods nor the protected ones. In both cases NoMethodError is thrown.

ruby

Conclusion: Private and protected methods cannot be called from the outside of the class. Access is restricted.

III Section

Topic: Access to private and protected methods from the inside of the defining class.

This time we have City::own_greeting which uses inherited protected method inside (`name_info`) and Country::own_greeting which uses inherited private method inside (`population_info`). Both private and protected methods (even if they are inherited) are accessible inside the class. So it’s not the point which distinguishes private from protected access.

ruby

Conclusion: Private and protected methods can be called from the inside of the defining class. Access is allowed.

IV Section

Topic: Actual difference between private and protected methods.

IV Section - More unexpected rules can start appearing here.

You can see 3 public methods there:

  • more_densely_populated?(other_region) - it uses private population_density inside.

  • the_same_continent?(other_region) - it uses protected continent inside.

  • can_be_crowdy? - it uses private consider_as_densely_populated? inside.

Let’s go through the code step by step:

more_densely_populated?(other_region)

ruby

Hmm, that’s interesting. Private method Region::population_density hasn’t been called, even though it is implemented inside the Region class. The similar scenario has been worked in the III section...

ruby

This one works. Any difference here? Right, the_same_continent? uses protected attribute - continent. Ok, let’s continue.

ruby

NoMethodError again. Hmm, can_be_crowdy? also uses private consider_as_densely_populated? method. Similar situation was working fine in the III section. So what’s going on here?

It’s all about the receiver.

Basically the receiver is the object whose method is invoked. Let’s go straight to the examples:

  • other_region.population_density ? - The receiver is other_region.

  • other_region.continent - The receiver is other_region.

  • self.consider_as_densely_populated? - The receiver is self.

And here is the important stuff, remember that rule: Private methods cannot be called with an explicit receiver.

Pay attention to the word 'explicit' here. Simplifying this statement - you cannot call private method by writing the invocation like this - object.some_method. You need to use pure some_method. In the latter case Ruby uses the implicit receiver, which is always self. Regardless of that fact, you still cannot call a private method by self.some_method, cause it’s still an explicit receiver, and rules are rules :)

Going back to our methods:

other_region.population_density ? - The explicit receiver is present and the method is private - NoMethodError

other_region.continent - The explicit receiver is present and the attribute is protected - OK

self.consider_as_densely_populated? - The explicit receiver is present and the method is private - NoMethodError

Conclusion: This is the actual distinction between private and protected. Private methods cannot be called with an explicit receiver and protected ones can. Based on my experience, protected methods are rarely used among Ruby code lines, but they can be useful while comparing parameters, for example, when we want to restrict access to the attribute but still want to use it in the comparison method.

I hope that the access control rules are much more clear now. I encourage you to get your hands dirty with the code if you hadn’t done it already. Theory tends to get forgotten if it isn't proofed.

In the end, as I promised - answers to the statements:

  1. TRUE

  2. TRUE

  3. FALSE

  4. FALSE

  5. TRUE

Summary

I’ve written this article because for me it was also surprising how public, private and protected access actually work in Ruby. The simplest things are the hardest to understand, or at least they can be. I really hope that this article was helpful for you. Or perhaps, you were aware of the access rules before reading it. Share your thoughts in the comments, I’m very curious of them. You can take a look at the docs too. You will find all these details there.

Let’s Create a Great Website Together

We'll shape your web platform the way you win it!

More posts in this category

  • February 05, 2025 • 10 min read

    API-first CMS: What Options You Have (Web Dev Agency's Take)

    According to the 2024 State of the API Report by Postman, 74% of organizations are adopting API-first strategies. This statistic isn’t just impressive—it signals a major shift in how businesses operate. While API-first approaches have long been a staple in software development, they're now reshaping content management as well. More and more companies are realizing that traditional CMS platforms can't keep up with the demand for flexibility, speed, and seamless integrations.

    READ MORELearn more about api first cms
  • January 23, 2025 • 15 min read

    Best CMS for SaaS: Top Cloud-Based Solutions

    Choosing the right Content Management System (CMS) is a critical decision for your SaaS business. Your unique needs require solutions that are not only flexible, scalable, and user-friendly but also tailored to meet the demands of a fast-paced, customer-focused industry. A CMS should simplify your workflows and help you deliver personalized, high-quality digital experiences.

    READ MORELearn more about best cms for saas top cloud based solutions
  • December 12, 2024 • 10 min read

    We Picked the Best (Headless) CMS for Vue

    Picture a digital experience where content effortlessly flows across platforms, development is agile, and performance is unmatched. By combining the power of Vue.js, a progressive JavaScript framework, with a modern headless CMS, you can achieve all this and more.

    READ MORELearn more about headless cms for vue