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
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
elden_ring = Game.new('Elden Ring')
elden_ring.developer_of_game('FromSoftware')
elden_ring.developer
# => 'FromSoftware'
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
elden_ring = Game.new('Elden Ring')
elden_ring.print_out_self
# => #<Game:0x00007fd9910c45a0 @name='Elden Ring'>
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
elden_ring = Game.new('Elden Ring')
dead_space = Game.new('Dead Space')
Game.all
# => [#<Game:0x00007fd9910c45a0 @name='Elden Ring'>, #<Game:0x00007fd9900dba58 @name='Dead Space'>]
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
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)