The protected modifier in Ruby
Tags: ruby, rails, beginners, programming
Published: 2022-01-20 22:59:34

Recruitment interviews, especially their technical part, usually follow a specific pattern. It is easy to anticipate the questions that may be asked. It is often the case that the developer who asks them is taken out of the project and busy with solving problems on a daily basis and does not have time to prepare some original and surprising questions (unless he is a sadist and likes to bully candidates, but who of us did not recruit and did not have a killer question up his sleeve?), so google for example "Ruby interview questions". The second possibility is that this developer is already on the nth interview, always asking the same questions out of pure routine. He may also ask what he himself was asked about when he was the candidate. I want to present to you and explain an issue that will appear in 90% of a job interview for a Ruby on Rails developer, and **it is about the Protected modifier in Ruby**.

##What's the difference between Public, Private, and Protected, which are access modifiers?

Sounds familiar?

You may encounter these words in other languages. To understand their slightly different meaning in Ruby, let's take a look at how they function in Java, C # and PHP for comparison.

##Java

**Public** - access to a method in a given package and in any other package

**Private** - access only within classes and not inheritable

**Protected** - This is almost identical to _private_, with one subtle difference, _protected_ methods can be inherited

##"C#"

**Public** - access to the method is unlimited from anywhere in the application

**Private** - methods available only within the class or structure in which they are defined

**Protected** - the method is available in the child class only if accessed through the child class

##PHP

**Public** - the method is visible from the inside of the class, derived classes and outside the class

**Private** - methods available only from inside the class

**Protected** - the method is visible in all classes that inherit from the base class, including the base class

##RUBY 💖💋💪

First, to be perfectly clear, these three words: **public**, **private**, **protected**, commonly referred to as **access modifiers**, are not really keywords, but ... **methods**.

Remember that in Ruby, the code which does something is called **method**, and is defined by the words def and end at the beginning and end of a given batch of code.

##Public in Ruby 

It is no different from any other language. In Ruby, all methods not explicitly specified by the other two modifiers are public, except for the class constructor, **the initialize** method, which is always private.

Public methods can be invoked by anyone, anywhere, and are therefore not subject to any restrictions. For the method to be public, no keyword is required, it is enough to declare it above the **private** and **protected** declarations.

**Interesting fact!**

Globally declared public methods outside of all classes are actually private methods of an instance of **Object**, Ruby's super extra mother class.

##Private in Ruby

The recipient of a private method is always **self**.

They cannot be called for any instance of the class in which they are defined, because they operate only inside that class, which means that 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 function style, that is:

`private_method ()`

not

`instance.private_method ()`

or

`self.private_method ()`

It also follows that the private methods of another object cannot be accessed, even if that object is of the same class.

##Protected in Ruby

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

They can always be called on behalf of any instance of a class or a subclass of it, so unlike private, they are not limited to only implicit calls on behalf of 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 the internal state, but at the same time prevents consumers of that class from accessing this state from the outside.

To quote **Matz, the creator of Ruby**:

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

Here are some examples to better understand the **Protected** modifier in Ruby.

We have **the Employee** class and two employees who symbolize its instances. Suppose a scenario where the boss wants to compare their salaries without exposing them to the outside world.

```ruby
class Employee
  attr_reader :salary
  protected :salary

  def greater_salary_than(other_employee)
    @salary > other_employee.salary
  end
end

first_employee = Employee.new
second_employee = Employee.new
first_employee.grater_salary_than(second_employee)

class Person
  def older_than?(other_person)
    age > other_person.age
  end

  protected
  def age@age
  end
end
```

You can clearly see what I wrote about above. **A protected method is not available outside the context of a given object, but is available inside the context of another object, if and only if the object is of the same type.**

![The_protected_modifier](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fspbvqot6fvyrykdmg2l.gif)

##Additional information about Protected in Ruby and other modifiers

- protected method can be called in the context of the given object as `method ()` or `self.method ()`
- Access modifiers can be declared in two ways:
- all methods after the word private will be private unless we use protected somewhere along the way. Similarly, all methods after this declaration will be protected, unless we use the private modifier somewhere along the way
- the second way is to first declare all the methods and then establish their access by listing their names in conjunction with the appropriate access modifier

```ruby
# I way
private
def method

protected
def method 

# II way
def method
end

protected :method
```
- calling `respond_to?` for a protected method it 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 does not include private methods. They can be considered by passing the second argument to this method as `true`
- let's go back to private methods for a moment. Although I wrote that we do not have access to them, there is one exception here. A trick known only to those who don't speak Rabi. Namely, you can get to them by calling the private method with the `send` method or by evaluating the block in the context of the object using the `instance_eval` method

```ruby
p = Page.new
p.send :some_private_method
p.instance_eval(some_private_method)

```
This is a topic for another lecture, treat it as a Swiss curiosity, don't try it at home.

BTW, there is also a `public_send` method which works like `send`, except that private methods are omitted. It's easy to get confused.