Ruby Method Visibility Summarized

Today I learned about Ruby’s method visibility and would like to make a summary on it.

While Java’s private method can only be accessed by the class itself, and Java’s protected can be accessed by the package and subclasses. Ruby’s private and protected are a little different. Ruby’s private and protected are about the receiver of the method.

Implicit receiver vs Explicit receiver

If we have a private method called secret_message(), it can only be accessed if the method receiver is an implicit receiver, it will fail if the receiver is an explicit receiver. Below is an explanation of what it means by implicit and explicit receiver:

An example of implicit receiver, where the receiver of the method is not specified: secret_message()

An example of explicit receiver, where the receiver is specified(this will give error): BaseClass.new.secret_message()

By sticking to this rule, private method can eventually be called within the class itself.


Code Example:
Private:

Passing example, secret_message() is called with an implicit receiver.

class BaseClass
  def public_method
    secret_message ## TAKE NOTE ##
  end

  private
  def secret_message
    puts "greetings from #{self.class}"
  end
end

class SubClass < BaseClass
end

BaseClass.new.public_method
SubClass.new.public_method
#---output---
# greetings from BaseClass
# greetings from SubClass

Failing example, secret_message() is called with an explicit receiver, self:

class BaseClass
  def public_method
    self.secret_message ##<--changes, TAKE NOTE ##
  end

  private
  def secret_message
    puts "greetings from #{self.class}"
  end
end

class SubClass < BaseClass
end

BaseClass.new.public_method
SubClass.new.public_method
#---output---
# NoMethodError: private method `secret_message' called for #<BaseClass:0x007f8430885188>
# NoMethodError: private method `secret_message' called for #<SubClass:0x007f84308f07f8>

Protected:
For protected, it allows the access if the receiver is self:

class BaseClass
  def public_method
    self.secret_message ##<--changes, TAKE NOTE ##
  end

  protected ##<--changes, TAKE NOTE ##
  def secret_message
    puts "greetings from #{self.class}"
  end
end

class SubClass < BaseClass
end

BaseClass.new.public_method
SubClass.new.public_method
#---output---
#greetings from BaseClass
#greetings from SubClass
Advertisements

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 )

Google+ photo

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

Connecting to %s