Same Sender and Receiver

In this chapter, you will learn that when the sender and receiver are the same, we cannot use an explicit receiver to call a private method.

Functional Form

Let's define a private method start() in Car. And call it within drive() method in functional form.

class Car
  def drive
    start
  end

  private

  def start
    p 'starting...'
  end
end

c = Car.new
c.drive

This prints:

starting...

Explicit Receiver

Let's use an explicit receiver to call the start() private method.

class Car
  def drive
    self.start
  end

  private

  def start
    p 'starting...'
  end
end

c = Car.new
c.drive

This prints:

 NoMethodError: private method ‘start’ called for <Car:0x007fc5d303ee68>

This results in the same output as the following:

class Car
  private

  def start
    p 'starting...'
  end
end

c = Car.new
c.start

The self and the Receiver

Let's check the value of self inside the drive() method and the receiver of the drive() method.

class Car
  def drive
    p "self is : #{self}"
    self.start
  end

  private

  def start
    p 'starting...'
  end
end

c = Car.new
p "receiver is : #{c}"
c.drive

This prints:

receiver is : #<Car:0x007fdd8c1c5900>
self is :     #<Car:0x007fdd8c1c5900>
NoMethodError: private method ‘start’ called for #<Car:0x007fdd8c1c5900>

Inside the drive method the sender and receiver are the same. The sender and the receiver objects are the same instance of Car class. In such cases, Ruby does not allow providing an explicit receiver when you want to call a private method.

Same Sender and Receiver

Same Sender and Receiver

The Public Method

If you make the start() method public, it will work.

class Car
  def drive
    self.start
  end

  def start
    p 'starting...'
  end
end

c = Car.new
c.drive

As expected, this prints:

driving...

The Protected Method

Let's change the start() method to protected.

class Car
  def drive
    self.start
  end

  protected

  def start
    p 'starting...'
  end
end

c = Car.new
c.drive

It still works.

Summary

You learned what happens when the receiver and the sender objects are the same when calling a private method. In such cases:

  • You cannot provide an explicit receiver to call a private method.
  • There is no receiver and dot symbol to send a message.
  • You have to call the private method in functional form.

results matching ""

    No results matching ""