Ruby: SELF in instance and class methods
Tags: ruby, beginners, programming
Published: 2022-08-23 14:15:00

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] (https://en.wikipedia.org/wiki/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. 
```javascript
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.

```javascript
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:
```javascript
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`:
```javascript
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:

```javascript
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.