Access Control in Ruby

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 !!!

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine

Advertisement

Leave a Comment

Filed under Ruby, Ruby on Rails

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s