The difference between Public, Private and Protected methods in Ruby
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 method
method1' 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 method
method1' 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.
self.method1 is accessible in 6.1.