After stumbling upon the access level modifiers for a long time, one day I decided to understand the ins-and-outs about the concept of public, protected and private in Ruby.
Let’s understand the concept of Access Control in Ruby with the help of some simple examples:
Understanding Private methods in Ruby:
Example 1
def MyClass
def one
puts “From one”
end
def two
one
end
private :one
end
mc = MyClass.new
mc.two # From one
NOTE: In the method “two”, the implicit receiver is “self”, where “self” is the instance “mc”
Pretty obvious output, as expected.
Let’s take a deep dive:
Example 2
class MyClass
def one
puts “From one”
end
def two
MyClass.new.one
end
private :one
end
mc = MyClass.new
mc.two # ?
The output here is:
NoMethodError: private method ‘one’ called for <MyClass:0x3074f24>
Before we get into the details, let’s consider a couple more examples:
Example 3
class MyClass
def one
puts “From one”
end
def two
self.one
end
private :one
end
mc = MyClass.new
mc.two # ?
The output here is:
NoMethodError: private method ‘one’ called for <MyClass:0×3067540>
One last example with private and we should be good to conclude.
Example 4
class MyClass
def one
puts “From one”
end
private :one
end
class MySubClass < MyClass
def two
one
end
end
mc = MySubClass.new
mc.two # ?
The output here is:
>From one
To conclude:
Private Visibility:
1. Private methods are private to the instance (and not to the class).
2. Private methods are accessible from sub-classes.
3. While accessing private methods, you cannot specify the receiver (even if its “self”), receiver is always implicit, never explicit.
4. “Private” in Ruby is what “Protected” is in many other languages.
5. In Ruby, no method is perfectly private or hidden.
Understanding Protected methods in Ruby:
Example 5
class MyClass
def one
puts “From one”
end
def two
one
MyClass.new.one
self.one
end
private :one
end
mc = MyClass.new
mc.two # ?
The output here is:
>From one
>From one
>From one
To conclude:
Protected Visibility:
1. Protected methods are visible to all the instances of the same class as well as sub-classes.
2. Protected methods are also accessible from sub-classes. In short, Access control in Ruby neither applies to nor impacts the object hierarchy.
3. While accessing protected methods, you can specify the receiver, receiver can by explicit or implicit.
4. “Protected” in Ruby is not quite common in other programming languages.
5. What’s the use if its accessible to all the instances as well as from sub-classes?
Private and Protected methods are not directly accessible outside the class.
Public Visibility:
1. The default access level is “Public”. Public methods are accessible from anywhere*.
(*anywhere – within the class, outside the class, same instance, other instances of same class and sub-classes)
Important: Also, in a subclass, one can override the access level modifier specified for any given action in the parent class.
Hope this helps understanding the basics of Access Control in Ruby. As always said, Ruby is truly object-oriented.
With this said, Access Level Modifiers should not be a hurdle hereon.
Food for Thought:
Private and Protected method declaration in Ruby is by-passed by the
message sending syntax.
class MyClass
def one
puts “From one”
end
private :one
end
mc = MyClass.new
mc.one # NoMethodError: private method 'one' called for <MyClass:0x3089244>
mc.send(:one) # From one
I haven’t been able to figure out the reason for this ambiguity in Ruby, the research is still on. If anyone has any ideas, please keep me posted.
In Ruby 1.9, we have a new method defined in the “Object” class named “public_send”. This respects the access level modifiers specified for any given action.
Happy coding !!!









