Private vs Protected in Ruby

Do you know the difference between private and protected methods before and after ruby 2.7?

Tushar Adhao
2 min readFeb 6, 2021

Let’s get straight to the point by setting up the scenario for the private method first and then for the protected method as below,

Photo by Kerrie DeFelice on Unsplash

Private

Consider a scenario where we have Product class with some public methods and print_message as private method.

class Product  def public_method1
print_message # direct call without self
end
# Don't miss special NOTE for this method below
def public_method2
self.print_message # direct call with self
end
def public_method3
Product.new.print_message # call with new/other instance
end
private def print_message
puts "In private method"
end
endproduct = Product.newproduct.print_message
# => private method `print_message' called for #<Product:0x0000564957f70688> (NoMethodError)
product.public_method1
# => "In private method"
product.public_method2
# => "In private method"
product.public_method3
# => private method `print_message' called for #<Product:0x000055e762dac3d0> (NoMethodError)

Observations:

  1. The private methods can be called in the following cases,
    when called (with or without self) within the public method of the same class and then the public method can be called from outside of the class
    product.public_method1 # => "In private method"
  2. The private methods cannot be called in the following cases,
    ✘ when called directly from outside of class it is defined
    product.print_message # => (NoMethodError)
    ✘ when called with a different instance object within the public method
    Product.public_method3 # => (NoMethodError)

Note: Before ruby 2.7 calling private method from public method with self (ex.self.print_message) use to give error as shown below,
product.public_method2 # => (NoMethodError)

Protected

Keeping the above scenario same, let’s replace private by protected so as to make print_message method protected.

class Product  def public_method1
print_message # direct call without self
end

def public_method2
self.print_message # direct call with self
end
def public_method3
Product.new.print_message # call with new/other instance
end
protected def print_message
puts "In protected method"
end
endproduct = Product.newproduct.print_message
# => protected method `print_message' called for #<Product:0x00005563e23881c8> (NoMethodError)
product.public_method1
# => "In protected method"
product.public_method2
# => "In protected method"
product.public_method3
# => "In protected method"

Observations:

  1. The protected methods can be called in the following cases,
    when called within the public method of the same class and then the public method can be called from outside of the class product.public_method1 # => “In protected method”
    when called with a different instance object within the public method
    Product.public_method3 # => “In protected method”
  2. The protected methods cannot be called in the following cases,
    ✘ when called directly from outside of the class in which it is defined
    product.print_message # => (NoMethodError)

Note: The protected methods have slower response time than the private methods. So it is adviced to use private methods more than protected methods.

--

--

Tushar Adhao
Tushar Adhao

Written by Tushar Adhao

Software artist spreading nuggets of coding gold and sometimes philosophy too.

Responses (2)