Understanding how Ruby initializes objects
Tags: ruby
Published: 2019-07-31 18:50:37

---
title: Understanding how Ruby initializes objects
published: true
tags: ruby
canonical_url: https://prathamesh.tech/2019/05/26/understanding-how-ruby-initializes-objects/
---

 ![Understanding how Ruby initializes objects](https://prathamesh.tech/content/images/2019/06/age-barros-572456-unsplash.jpg)

Deep buried in Rails source code, there is a [code snippet](https://github.com/rails/rails/blob/4a86464cbae007f9bf37189bd265eac8415570c5/activesupport/lib/active_support/deprecation/proxy_wrappers.rb#L6-L12):

<!--kg-card-begin: code-->
```
class DeprecationProxy
  def self.new(*args, &block)
    object = args.first

    return object unless object
    super
  end
  ...
end
```
<!--kg-card-end: code-->

It was added 9 years ago and the commit message said:

<!--kg-card-begin: code-->
```
Override new on proxy objects so that they never wrap nil or false.
```
<!--kg-card-end: code-->

The question is that how does this work? Because we know that when an object is initialized using `new`, Ruby executes the `initialize` method.

<!--kg-card-begin: code-->
```
class Greeting
  def initialize(message)
    puts "Hello there! #{message}"
  end
end

Greeting.new("Welcome to Ruby world.")
=> "Hello there! Welcome to Ruby world."
```
<!--kg-card-end: code-->

Notice that we have not actually defined `new` method anywhere. So how does this code from Rails work?

To see how things work under the hood, let’s introspect where the `new` method is defined on the class.

Ruby provides a handy method which is named `method` to see where a method is defined.

<!--kg-card-begin: code-->
```
>> Greeting.method(:new)
=> #<Method: Class#new>
```
<!--kg-card-end: code-->

We can see that the `new` method actually comes from `Class`. But then how does the `initialize` method gets called when we call `new` on a class?

Turns out, Ruby internally calls `initialize` on the object passing all the arguments that were passed to `new`.

<!--kg-card-begin: code-->
```
greeting = Greeting.new(message)
=> Calls Class.new(message)
=> Calls initialize on the object
=> which results in:
=> greeting.initialize(message)
```
<!--kg-card-end: code-->

As Ruby allows us to override any method, we can override the `new` class method as well.

<!--kg-card-begin: code-->
```
class Greeting
  def self.new(args)
    puts args
    puts "New ends here."
  end

  def initialize(args)
    puts "I am getting initialized with #{args}"
  end
end
```
<!--kg-card-end: code-->

Let’s see what is the output of creating an object of the Greeting class now.

<!--kg-card-begin: code-->
```
Greeting.new({name: "Prathamesh", country: "India"})

>> Greeting.new({name: "Prathamesh", country: "India"})
{:name=>"Prathamesh", :country=>"India"}
New ends here.
=> nil
```
<!--kg-card-end: code-->

As expected, Ruby happily calls the overridden `new` method and no longer calls the `initialize` method because we did not call it from our definition of `new`.

Now let’s look at the snippet from Rails that we discussed earlier:

<!--kg-card-begin: code-->
```
class DeprecationProxy
  def self.new(*args, &block)
    object = args.first

    return object unless object
    super
  end
  ...
end
```
<!--kg-card-end: code-->

It is clear that the `new` method is overridden by the `DeprecationProxy` class and it returns same object when the object has a falsey value.

<!--kg-card-begin: code-->
```
return nil unless nil
return false unless false
```
<!--kg-card-end: code-->

It should also be noted that this overridden `new` method calls `super` on the last line which in turn calls `Class#new`. This makes sure that Ruby’s semantics of `new` method are preserved. This will make sure that `DeprecationProxy.new`will call `initialize` method of `DeprecationProxy` after the overridden `new`method is executed.

Subscribe to my [newsletter](https://www.prathamesh.tech/mailing-list) to know more about how Ruby works by prying out Rails code.