DEV Community

rossonevan
rossonevan

Posted on • Edited on

Ruby: SELF in instance and class methods

After learning about the front-end of web development through JavaScript and React, it was time to venture to the back-end, Ruby. Object-Oriented Programming (OOP) is a type of programming based on the concept of "objects", which can contain data, in the form of fields (often known as attributes or properties) and code, in the form of procedures (also known as methods). OOP allows web developers to structure code so that its functionality can be shared throughout the application.

Self in Instance Methods

Ruby, because of OOP, uses classes to identify their objects. A class is like a template, or a blueprint, for creating objects with similar characteristics. When creating a class, each new instance of that class is called an object. This object is a bundle of code that contains both data and behaviors. Inside each class, developers can create numerous instance methods.

class Game

  attr_accessor :name

  def initialize
    @name = name
  end

  def developer_of_game(name, developer_name)
    name.developer = developer_name
  end
end
Enter fullscreen mode Exit fullscreen mode

In the example above, we use the attr_accessor macro in order to make changes to the name attribute. The #developer_of_game instance method takes in an object of Game and assigns a name to that instance. But there is an easier, DRY-er, way we can get the same result: by using self. self refers to whatever instance the method is called on.

class Game

  attr_accessor :name

  def initialize
    @name = name
  end

  def developer_of_game(developer_name)
    self.developer = developer_name
  end
end
Enter fullscreen mode Exit fullscreen mode
elden_ring = Game.new('Elden Ring')
elden_ring.developer_of_game('FromSoftware')
elden_ring.developer
# => 'FromSoftware'
Enter fullscreen mode Exit fullscreen mode

By placing self inside the instance method, the method takes the specific object that we created and applies it to the method. By printing out self, we can see that it is an instance of the class and it's own unique object:

class Game

  attr_accessor :name

  def initialize
    @name = name
  end

  def print_out_self
    puts self
  end
end
Enter fullscreen mode Exit fullscreen mode
elden_ring = Game.new('Elden Ring')
elden_ring.print_out_self
# => #<Game:0x00007fd9910c45a0 @name='Elden Ring'>
Enter fullscreen mode Exit fullscreen mode

Self in Class Methods

We can use self on class methods as well. From our last example, we can create a class method by using self:

class Game

  attr_accessor :name

  @@all = []

  def initialize
    @name = name
    @@all << self
  end

  def developer_of_game(developer_name)
    self.developer = developer_name
  end

  def self.all
    @@all
  end
end
Enter fullscreen mode Exit fullscreen mode
elden_ring = Game.new('Elden Ring')
dead_space = Game.new('Dead Space')
Game.all
# => [#<Game:0x00007fd9910c45a0 @name='Elden Ring'>, #<Game:0x00007fd9900dba58 @name='Dead Space'>]
Enter fullscreen mode Exit fullscreen mode

NOTE: The self inside the #developer_of_game method is NOT the same as the self in the self.all.

Game.all produces an array of all the Game. The @@all is a class variable that is initially set as an empty array []. In our initialize method, each individual instance's self is inserted into the @@all variable. Once the self.all class method is called, that array will contain all of the instances of the Game class that were created because the method is being called on the entire class rather than one instance of the class. Finally, we have to call the @@all class variable inside our self.all to be able to read it. If we wanted to only get the names of each game, we can .each the self.all class method we just defined inside another class method:

def self.print_all_game_names
    self.all.each do |game|
      puts game.name
    end
end
Enter fullscreen mode Exit fullscreen mode

Conclusion

The most important thing to remember when it comes to self: When using self inside an instance method, it is one object of that class that the method is called upon. When using self on a class method, it is the entire class itself.

Top comments (0)