Self in Ruby

3 Min. Read
Aug 18, 2019

Introduction

self is a special variable that points to the currently executing object. self can be used along various parts in our program and can refer to the different things depending upon where it is used. Some of the basic usecase for self can be as follows:

  1. self can be used when calling setter method which helps Ruby to disambiguate between initializing the local variable or to call a setter method

  2. It can be used for class definition method

self for calling a setter method

let’s assume we have a basic class named Dog along with the methods attr_accessor that takes the symbol as argument, an alternative to the getter and setter method, initialize for initializing the variable for an instance object, change_info for changing the object’s attribute, and info that displays the states of the object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Dog
  attr_accessor :name, :height, :weight

def initialize(n,h,w)
  @name = n
  @height = h
  @weight = w
end

def change_info(n,h,w)
  @name = n
  @height = h
  @weight = w
end

def info
  "The #{name} weighs #{weight} and is #{height} tall."
end

bruno = Dog.new('Bruno', '30 inches', '30kg')
puts bruno.info     # => Bruno weighs 30kg and is 30 inches tall
bruno.change_info('Fido','20 inches','20kg')
puts sparky.info    # => Fido weighs 20 kg and is 20 inches tall
end

In above code, we created the new Dog object, initialize the variable and called info method which return certain data. To notice we could also use @name,@weight, and @height inside the info method. But, when we replace @name,@height,@weight to name, height, weight respectively in change_info method as

1
2
3
4
5
def change_info(n,h,w)
  name = n
  height = h
  weight = w
end

The above method will not be able to change the object attribute because Ruby instead of calling name=, height=, weight= setter methods ,it thought only local variables name,height, weight were created. To disambiguate from creating local variable, we need to use self.name so that ruby knows we are calling the methods.For e.g

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Dog
    attr_accessor :name, :height, :weight

    def initialize(n,h,w)
      @name = n
      @height = h
      @weight = w
    end

    def change_info(n,h,w)
      self.name = n
      self.height = h
      self.weight = w
    end

    def info
      "The #{name} weighs #{weight} and is #{height} tall."
    end
end 

bruno = Dog.new('Bruno', '30 inches', '30kg')
puts bruno.info          # => Bruno weighs 30kg and is 30 inches tall
bruno.change_info('Fido','20 inches','20kg')
puts sparky.info         # => Fido weighs 20 kg and is 20 inches tall

self for class method definition

The other place we use self is when we’re defining class methods, such as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog
    @@number_of_dogs = 0

    def initialize
      @@number_of_dogs +=1
    end

    def self.total_dogs
      @@number_of_dogs
    end
end 
puts Dog.total_number_dogs   # => 0

dogObj = Dog.new

puts Dog.total_number_dogs   # => 1


Above, @@number_of_dogs is a class variable which can be access via initialize method whereas self.total_dogs is a class method which only includes the details related only to the class but not to the objects.In this way, self scope changes depending upon where it is defined in.