Basics of Protected Methods in Ruby 2.2.3

Objective


To learn the basics of protected methods in Ruby


Calling a Protected Method from an Instance of a Given Class

class Car
  protected

  def shift
    p 'shifting'
  end
end

c = Car.new
c.shift

We get the error:

NoMethodError: protected method ‘shift’ called for #<Car:0x007f>

when we run this program. So the protected method cannot be called by an instance of Car.

Calling a Protected Method from an Instance of a Given Subclass

Can an instance of a subclass of Car call protected method?

class Car
  protected

  def shift
    p 'shifting'
  end
end

class Beetle < Car
end

b = Beetle.new
b.shift

We get the error:

NoMethodError: protected method ‘shift’ called for #<Beetle:0x007f>

How Can the Subclass call the Protected Method?

class Car
  protected

  def shift
    p 'shifting'
  end
end

class Beetle < Car
  def start
    shift
  end
end

b = Beetle.new
b.start

This prints shifting. So we can call the protected method from a public method of the subclass.

Comparison with Private Method

Let's compare the above example to private method, if you change the protected to private:

class Car
  private

  def shift
    p 'shifting'
  end
end

class Beetle < Car
  def start
    shift
  end
end

b = Beetle.new
b.start

It still works. In this case it is better to use private than protected to hide the implementation details.

Comparison with Class Method

If the shift() method is a class method, we can call the method inside the class like this:

class Car
  protected

  def self.shift
    p 'shifting'
  end
end

class Beetle < Car
  shift
end

This will print shifting. In this case we don't need to create an instance and invoke the class method.

Calling Protected Method from Other Instances of a Given Class

Protected method can also be called from other instance of the Car class. Here is an example:

class Car
  def start
    c = Car.new
    c.shift
  end

  protected

  def shift
    p 'shifting'
  end
end

c = Car.new
c.start

This prints shifting. In the start method, we create an instance of Car and this instance is able to invoke the protected method shift. Let's compare this to the private method, if you change protected to private:

class Car
  def start
    c = Car.new
    c.shift
  end

  private

  def shift
    p 'shifting'
  end
end

c = Car.new
c.start

You will get NoMethodError: private method ‘shift’ called for #<Car:0x007fe> error. So using protected in this example provides access to the shift method from other instances of the Car class.

Summary


In this article we saw two different ways to invoke protected methods in Ruby. A subclass can call the protected methods defined in its parent from a public method. Protected methods can also be called from other instances of the class defining the protected method.

Reference


Ruby 2 Methodology by Akira Matsuda


Related Articles


Create your own user feedback survey