What does "class << self" actually do in Ruby?
Tags: ruby, programming, beginners
Published: 2021-11-07 18:44:16

As a ruby developer, you almost certainly have seen `class << self` definition inside a class. Methods defined within `class << self` block become class methods. Here's an example.
```ruby
class Greeting
  class << self
    def hello
      puts "Hello!"
    end
  end
end
```

Now `hello` method can be called on the `Greeting` class.
```
>> Greeting.hello
Hello!
```

You can also add a class method like this.
```ruby
class Greeting
  def self.hello
    puts "Hello!"
  end
end
```

The end result will be the same. Does it mean that `class << self` is simply a syntactic sugar that allows adding class methods? Not exactly. To understand what `class << self` actually does, we must first understand what `self` is inside a class.

## What is self?
There's always a `self` object at any point in the Ruby code. Outside of any class/module/method definitions, `self` is a `main` object of the class `Object`.
```
>> puts self, self.class
main
Object
```

Inside a method within a class, `self` is the object of that class.
```ruby
class Greeting
  def whoami
    puts self, self.class
  end
end
```
```
>> Greeting.new.whoami
#<Greeting:0x00007ff03c8f6e78>
Greeting
```

And, within a class but outside of any method, `self` is the class object. In Ruby, classes are objects too. Every class is an object of the `Class` class.
```ruby
class Greeting
  puts self       # Greeting
  puts self.class # Class
end
```

## Using `class << obj` instead `class << self`
Now that we know that `self` is simply a class object, let's try to replace it with the actual class name and see how that works.
```ruby
class Greeting
  class << Greeting
    def hello
      puts "Hello!"
    end
  end
end
```

Works like a charm 😎
```
>> Greeting.hello
Hello!
```

So, `class << Greeting` is that same as `class << self`. Methods inside that block get added to the `Greeting` class object. But wait, since `Greeting` is an object, can we replace it with any other object? Can we use a non-class object? Let's try.
```ruby
obj = Object.new
class << obj
  def hello
    puts "Hello!"
  end
end
```
```
>> obj.hello
Hello!
```

Hmm... We are able to add methods to any object!
![Amazing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6kgq825ezvi6sgfpusv.gif)

## What `class << self` actually does
Turns out that `class << ...` doesn't necessarily have to be used with class objects. You can use it with any object.

So far we learned that:
1. Method defined within `class << obj` block will be added to the `obj` object.
2. `obj` can be any object.

`class << self` definition is used often within a class, that new Ruby developers might think that it's some kind syntactic sugar available only for classes which allows to add class methods. But now we know that it's not true.

## Singleton class
There's one more thing worth mentioning. `class << obj` block opens a *singleton class*. Every Ruby object has a singleton class. Methods defined within `class << obj` block are instance methods of the singleton class of the object `obj` 🤯 The most important thing to remember is that singleton class instance methods take precedence in the method lookup process. This example should explain more.
```ruby
class Greeting
  def hello
    puts "Hello!"  
  end
end

obj = Greeting.new

class << obj
  def hello
    puts "Hola!"
  end
end
```
```
>> obj.hello
Hola!
```

Singleton class is a regular class object which you can access using `#singleton_class` method. This method is available for all objects.
```
>> puts obj.singleton_class, obj.singleton_class.class
#<Class:#<Object:0x00007faf18146648>>
Class
```

Since it's just a class, you can list its instance methods.
```ruby
# Let's add one more method for the sake of example.
class << obj
  def hola
    puts "Hola!"
  end
end
```
```
>> obj.singleton_class.instance_methods(false)
=> [:hola, :hello]
```

The last thing I'd like to mention about the singleton class is that you can also define its instance methods using this syntax.
```ruby
def obj.hello
  puts "Hello!"
end
```

I hope now you see that all class methods(no matter whether they are defined using `class << self` or `def self.method` syntax) are actually instance methods of the singleton class of the class object.
![What](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1b9hpknbr4iwdqpk1w0.gif)


## Conclusion
1. `class << obj` block opens a singleton class 🙃
2. In that block we can defined instance methods of the singleton class 🧐
3. Those methods take precedence in the method lookup process 🚀
4. Singleton class is a regular class object 😁
5. Every Ruby object has its own singleton class which can be accessed via `#singleton_class` method 😎