TechEnthu

Difference between private and protected methods in ruby

Unlike java and other languages, Ruby private and protected methods work differently. It’s very important to know how it works!. In Ruby, the inheritance hierarchy don’t really a matter, it is rather all about which object is the receiver of a particular method call.

Private :-

When a method is declared private in Ruby, it means this method can never be called outside the class or explicit receiver. Any time we can call a private method inside the class or implicit receiver.
We can call a private method from within a class it is declared in as well as all subclasses of this class.

Example:


class Animal

   def some_method
      method_1
   end

   private

   def method_1
      puts "Hi I am a #{self.class}"
   end

end

class Dog < Animal

   def some_breed
       method_1
   end

end


Animal.new.some_method # Hi I am a Animal
Dog.new.some_breed # Hi I am a Dog

However, as soon as we try to call it outside the class or explicit receiver, even if the receiver is self, the method call will fail
Example:


class Cat < Animal

    def my_method
       self.method_1
    end

end


Cat.new.my_method #my_method ': private method method_1' called for #Cat:0x7f67025a0648 (NoMethodError)

We cannot call a private method outside the class or with an explicit receiver.

Protected :-

There is a small difference between protected and private methods. You can always call a protected method inside the class or with an implicit receiver, just like private, but in addition you can call a protected method with an explicit receiver as long as this receiver is self or an object of the same class as self.

Example:


class Animal

    def some_method
       method_1
    end

    protected

    def method_1
       puts "Hi I am a #{self.class}"
    end

end

class Dog < Animal

    def some_breed
       method_1
    end

end

class Cat < Animal

    def my_method
       self.method_1
    end

end


Animal.new.some_method # Hi I am a Animal
Dog.new.some_breed # Hi I am a Dog
Cat.new.my_method # Hi I am a Cat

Now, the call inside the clas or with an implicit receiver in class Dog succeeds as previously, but the call outside class or with the explicit receiver in class Cat also succeeds unlike when method_1 was private. Following is also fine:


class Lion < Animal

    def my_roar
       Dog.new.method_1
    end

end

Lion.new.my_roar # Hi I am a Dog

Everything works because Dog.new is the same type of object as self and so the call to method_1 succeeds. If however we make class Horse NOT inherit from Animal, we get the following:


class Horse # not inherting from Animal class

   def my_ride
      Dog.new.method_1
   end

end

Horse.new.my_ride # my_ride ': protected method method_1' called for #Horse:0x7fe81d00efa8 (NoMethodError)

In this case Dog.new is no longer the same type of object as self and so trying to call a protected method with Dog.new as the receiver – fails.

Public :- 

Public methods are accessible inside the class or outside the class from anywhere. Inside the class becomes implicit receiver and outside class becomes explicit receiver.