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