The Protected Modifier in Ruby

12 marca 2025
ruby

The Protected Modifier in Ruby

Job interviews, especially their technical part, usually follow a certain pattern. It's easy to predict what questions might come up.

Often, the developer asking them is pulled from a project and busy solving problems on a daily basis. They don't have time to prepare super original questions (unless they're a sadist who enjoys tormenting candidates, but who among us hasn't conducted recruitment and didn't have a killer question up their sleeve?), so they Google something like "Ruby interview questions."

The second possibility is that this developer is conducting their nth interview and, out of pure routine, always asks the same questions. They might also ask about what they themselves were asked when they were a candidate.

I want to present and explain an issue that will almost certainly (90% chance) appear in a Ruby on Rails developer interview, and that's what the Protected modifier is in Ruby.

What's the Difference Between Public, Private, and Protected Access Modifiers?

Sound familiar?

You might encounter these words in other languages. To understand their somewhat different meaning in Ruby, let's compare how they function in Java, C#, and PHP.

Java

Public – access to the method in a given package as well as in any other

Private – access only within classes and impossible to inherit

Protected – is almost identical to private, with one subtle difference: protected methods can be inherited

C#

Public – access to the method is unrestricted from anywhere in the application

Private – methods accessible only within the class or structure in which they are defined

Protected – the method is accessible in a child class only if access is done through the child class

PHP

Public – the method is visible from inside the class, derived classes, and outside the class

Private – methods accessible only and exclusively from inside the class

Protected – the method is visible in all classes that inherit from the base class, including the base class itself

RUBY 💖💋💪

First of all, for clarification, these three words: public, private, protected, commonly referred to as access modifiers, are not actually keywords, but... methods.

Remember that in Ruby, code that does something and can be called is referred to as a method, and it's defined by the words def and end at the beginning and end of a given piece of code.

Public in Ruby

It's no different from other languages. In Ruby, all methods not explicitly defined by the other two modifiers are public, with the exception of the class constructor, i.e., the initialize method, which is always private.

Public methods can be called by anyone and anywhere, so they are not subject to any restrictions. No keyword is required for a method to be public; it's enough that it's declared above the private and protected declarations.

Fun fact!

Public methods declared globally outside all classes are actually private methods of the Object class instance, which is Ruby's super extra mother class.

Private in Ruby

The recipient of a private method is always self.

They can't be called for any instance of the class in which they are defined, because they only work internally, within that class, which means they can only be called in the context of a given object.

They can only be called in other instance methods of the same class and its subclasses. Private methods in Ruby are inherited.

When using private methods in the body of other methods, remember that we always do it in a functional style, i.e.:

private_method()

and not

instance.private_method()

or

self.private_method()

It also follows that there is no access to the private methods of another object, even if that object is of the same class.

Protected in Ruby

Access to protected methods is restricted to family only, but compared to other languages, they can be called by objects of the same class, but inside those objects.

They can always be called on any instance of the class or its subclasses, so unlike private, they are not limited only to implicit calls on self.

Protected is used to operate on the internal state of other objects of the same class.

It is an access method that allows an instance of a given class to share internal state, but at the same time prohibits consumers of that class from accessing that state from the outside.

Quoting Matz, the creator of Ruby:

"A protected method defined in class C can be called on object O by a method in object P if classes O and P are subclasses of class C or are equal to it."

Time for examples to better understand the Protected modifier in Ruby.

We have an Employee class and two employees symbolizing its instances. Let's assume a scenario where the boss wants to compare their salaries while not revealing them externally.

This clearly illustrates what I wrote above. A protected method is not accessible outside the context of a given object, but is accessible within the context of another object, if and only if that object is of the same type.

Additional Information About Protected in Ruby and Other Modifiers

  • A protected method can be called in the context of a given object as method() or self.method()
  • Access modifiers can be declared in two ways:
  • Calling the respond_to? method for a protected method will return false. For clarification, respond_to? is a method that returns true if the object implements the method given as an argument. By default, it doesn't include private methods. You can take them into account by passing a second argument as true to this method
  • Let's go back for a moment to private methods. While I wrote that we don't have access to them, there is one exception. A trick known only to those who don't say Rabi. Namely, you can access them by calling a private method using the send method or by evaluating a block in the context of an object using the instance_eval method
  • This is a topic for another discussion - consider it a Swiss curiosity, don't try this at home.

    BTW, there's also a method called public_send, which works like send, except it skips private methods. Easy to confuse them.