The Dynamic Nature of self

In this chapter you will learn how the value of self changes as the program executes.

Car with Drive Method

Let's define a Car class with a drive() method.

class Car
  def drive
    'driving'
  end
end

We can create an instance of the car class and send a message to the car object.

car = Car.new
car.drive

This prints:

driving

The self Before Sending a Message

Let's see the value of self before we send the drive message to car object.

class Car
  def drive
    'driving'
  end
end

car = Car.new

p "Before sending the message, self is : #{self}"
car.drive

This prints:

Before sending the message, self is : main

The self After Sending a Message

Let's see the value of self after we send the drive message to car object.

class Car
  def drive
    'driving'
  end
end

car = Car.new

car.drive
p "After sending the message, self is : #{self}"

This prints:

After sending the message, self is : main

The self During Message Send

Let's check the value of self during the message send.

class Car
  def drive
    'driving'
  end
end

car = Car.new
car.tap { |x| p "The value of self is : #{x}"}.drive

This prints:

The value of self is : #<Car:0x007fc6bb912d08>

The value of self is the same as the car object.

Rhonda Asks

Where is the tap method defined?

Let's find out.

p Object.method(:tap)

This prints:

#<Method: Class(Kernel)#tap>

The tap method is in the Kernel module.

 > Kernel.methods.grep(/tap/)
 => [:tap]

Kernel is mixed in to Object.

 > Object.methods.grep(/tap/)
 => [:tap]

Thus, tap method is available on any object. It executes a code block, yielding the receiver to the block and returns the receiver.

Fabio Asks

Why does the following code print main, when I change code ?

car.tap { |x| p "The value of self is : #{self}"}.drive

The self printed inside tap is the same value of self as in the line above the tap call. This is due to closure in Ruby. You will learn about closures in a later chapter. You must print the block variable, if you want to peek inside the car object. We can verify it.

class Car
  def drive
    'driving'
  end
end

car = Car.new
car.tap { |x| p "The value of self is : #{x}"}.drive
p car

This prints:

"The value of self is : #<Car:0x007f854b141ea0>"
#<Car:0x007f854b141ea0>

The memory address of self and the car object is the same. Thus, they are the same object.

The Dynamic Nature of Self

The diagram illustrates the value of self before, during and after executing the drive method.

Rhonda Asks

What is self ?

The self refers to the object inside which the current method is executing. It is the receiver of the current executing method.

The self is Car Object

Summary

In this chapter, you learned that Ruby changes the value of self as it executes the program. There is always a self. The value of self changes to the current executing object and Ruby sends a message to that object. Once the method completes the execution, the value of self changes again. You know that self cannot be assigned any value to it. But you can use language constructs such as class, module and method declarations to make Ruby change the value of self. We will discuss this in the next chapter.

results matching ""

    No results matching ""