Codementor Events

The difference between Public, Private and Protected methods in Ruby

Published Apr 10, 2017

The concept of private, protected and public methods in Ruby is bit different than it other languages like Java.
In Ruby, the inheritance hierarchy or the package 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 with an explicit receiver. Any time we’re able to call a private method with an implicit receiver.
We can call a private method from within a class it is declared in as well as all subclasses of this class e.g.
class Foo
 
  def bar
    method1
  end
 
  private
 
  def method1
    puts "Hi this is #{self.class}"
  end
 
end
 
class Blah < Foo
 
  def main_method
    method1
  end
 
end
 
Foo.new.bar # Hi this is Foo
Blah.new.main_method # Hi this is Blah
 
 
However, as soon as we try to use an explicit receiver, even if the receiver is “self”, the method call will fail e.g.
 
class NewFoo < Foo
 
  def main_method
    self.method1
  end
 
end
 
NewFoo.new.main_method #main_method': private methodmethod1' called for #NewFoo:0x7f67025a0648 (NoMethodError)

In all You can’t call a private method with an explicit receiver, you can never call it from outside the class hierarchy where it was defined.
Protected: – Protected methods are also a bit different from private. You can always call a protected method 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. Let’s have a look at e.g.
 
class Foo
 
  def main_method
    method1
  end
 
  protected
 
  def method1
    puts "Hi this is #{self.class}"
  end
 
end
 
class Blah < Foo
 
  def main_method
    method1
  end
 
end
 
class NewFoo < Foo
 
  def main_method
    self.method1
  end
 
end
 
Foo.new.main_method # Hi this is Foo
Blah.new.main_method # Hi this is Blah
NewFoo.new.main_method # Hi this is NewFoo
 
 
Now, the call with the implicit receiver in class Blah succeeds as previously, but the call with the explicit receiver in class NewFoo also succeeds unlike when method1 was private. Furthermore, doing the following is also fine:

class NewBlah < Foo
  
  def main_method
    Blah.new.method1
  end
 
end
 
NewBlah.new.main_method # Hi this is Blah
 
 
Everything works because Blah.new is the same type of object as self and so the call to method1 succeeds. If however we make class NewBlah NOT inherit from Foo, we get the following:
 
class NewBlah
 
  def main_method
    Blah.new.method1
  end
 
end
 
NewBlah.new.main_method # main_method': protected methodmethod1' called for #NewBlah:0x7fe81d00efa8 (NoMethodError)

In this case Blah.new is no longer the same type of object as self and so trying to call a protected method with Blah.new as the receiver – fails.
Public: – Public methods are accessible with any kind of explicit or implicit receiver from anywhere.

Discover and read more posts from Anurag
get started
post comments1Reply
Sufyan Iqbal
4 years ago

self.method1 is accessible in 6.1.