Private and Protected Methods in Ruby

Private methods can only be called within the class in which they’re defined. If the Cat class defines a private method named meow(), it will only be accessible within the Cat class and not by other classes, like Dog.

class Cat
  def hungry
    meow
  end

  private

  def meow
    'miiiiiiiow'
  end
end

p Cat.new.hungry # => 'miiiiiiiow'

class Dog
  def fun
    "Making cats #{Cat.new.meow}"
  end
end

p Dog.new.fun # => NoMethodError: private method `meow' called

In other words, private methods cannot be called with an explicit receiver. Ruby relies on self as the implicit receiver whenever an explicit receiver is not specified.

Protected methods are similar to private methods and can only be called within the class in which they’re defined. Protected methods are slightly different from private methods because they can be called with an explicit receiver, but only when the explicit receiver equals self. The following example highlights this subtle difference.

class A
  def aaa
    self.bbb
  end

  private

  def bbb
    'bbb'
  end
end

# raises an exception because an explicit receiver is used
A.new.aaa # => NoMethodError: private method `bbb' called

class A
  def aaa
    self.bbb
  end

  protected

  def bbb
    'bbb'
  end
end

# doesn't raise an exception because the explicit receiver
# is self
A.new.aaa # 'bbb'

# exception is raised when A#bbb is called with an explicit
# receiver other than self, similar to private
A.new.bbb # => NoMethodError: protected method `bbb' called

The send() method can be used to easily bypass private and protected methods and call them with explicit receivers. The public_send() method is similar to dot notation and will raise an exception if a private method is called.

class House
  private
  def something
    'something'
  end
end

h = House.new
h.send(:something) # => "something"
h.public_send(:something) # => NoMethodError: private method `something' called
Advertisements

One thought on “Private and Protected Methods in Ruby

  1. Pingback: Ruby’s BasicObject#instance_eval method | Ruby/Rails Programming

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