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.