#---Self---

The self keyword in Ruby refers to the current object. So its value changes depending on where it is used.
It’s kinda like the this keyword in JavaScript.

self in a Class

class Dog
  def self.who_am_i
    self
  end
  def who_am_i
    self
  end
end

The self inside any class method refers to the class itself:

p Dog.who_am_i # => Dog

But the self inside any instance method refers to the specific instance of the class:

p Dog.new.who_am_i # => #<Dog:0x00007f8c1c0b2a20>

The self inside a class body, like this, also refers to the class itself:

class Dog
  p self
end

self in a Module

The self inside a module’s method depends on how the module is used:

module Trainable
  def trainable_who_am_i
    self
  end
end

If the module is included in a class, then self will refer to the instance of that class:

class Dog
  include Trainable
end
p Dog.new.trainable_who_am_i # #<Dog:0x00007f8c1c0b2a20>

But if it is extended, then self will refer to the class itself, not its object:

class Cat
  extend Trainable
end
p Cat.trainable_who_am_i # Cat

self Outside

What about self outside of a class, module or a method?

self, here, refers to the main object in Ruby. It’s a special object that belongs to the Object class:

p self # => main
p self.class # => Object

Implicit and Explicit Receivers

When you call a method or a function, you’re always calling it on an object:

## Here, `new` is called on the `Dog` class
p Dog.new
## `who_am_i` is called on the `Dog` instance
p Dog.new.who_am_i # => #<Dog:0x00007f8c1c0b2a20>

But there are times when you’ll come across a function that’s called without an explicit receiver. Like here:

class Dog
  def name
    "Pongo"
  end
  def speak
    ## Here, `name` is called without an explicit receiver
    "Woof! My name is #{name}."
  end
end

Or, like our friends p and puts, which are always called without an explicit receiver:

p "Hello"
puts "World"

In these cases, despite not having an explicit receiver, these method are still called on certain objects. Which ones? The ones referenced by self at that point in the code.

In the speak method above, name is called on the instance of the Dog class. In the p and puts methods above, they are called on the main object discussed earlier.

Uses of self

  • In some languages, there’s the concept of an execution context that is used to refer to the environment the current line of code is executing in. self is Ruby’s version of that. It can be of great use in debugging.
  • self can be used to chain methods of an object together. It’s a cool-looking design.
    For that to work, the methods need to return the object itself, which is usually done by returning self:
class Calculator
  def initialize
    @value = 0
  end
  
  def add(n)
    @value += n
    self # returns the calculator instance
  end
  
  def subtract(n)
    @value -= n
    self
  end
  
  def result
    @value
  end
end
calc = Calculator.new
p calc.add(5).subtract(3).add(2).result  # => 4

The Rails gem ActiveRecord implements method chaining.

  • self is used to distinguish between a local variable and a method with the same name.
class Dog
  attr_accessor :name
  
  def update_name(new_name)
    ## With self, this calls the setter method correctly
    self.name = new_name.upcase
    ## Without self, this creates a local variable.
    ## Comment the above and uncomment the below to see:
    ## name = new_name.upcase
  end
end
d = Dog.new
d.update_name("pongo")
p d.name  # => "PONGO"
#