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)