extend self in ruby
Following code was tested with ruby 1.9.3 .
Class is meant for both data and behavior
Lets look at this ruby code.
Here we have a
Util class. But notice that all the methods on this class are class methods. This class does not have any instance variables. Usually a class is used to carry both data and behavior and ,in this case, the Util class has only behavior and no data.
Similar utility tools in ruby
Now to get some perspective on this discussion lets look at some ruby methods that do similar thing. Here are a few.
In all the above casese the class method is invoked without creating an instance first. So this is similar to the way I used
However lets see what is the class of all these objects.
So these are not classes but modules. That begs the question why the smart guys at ruby-core implemented them as modules instead of creating a class the way I did for Util.
Reason is that Class is too heavy for creating only methods like
double. As we discussed earlier a class is suppossed to have both data and behavior. If the only thing you care about is behavior then ruby suggests to implement it as a module.
extend self is the answer
Before I go on to discuss
extend self here is how my
Util class will look after moving from
So how does extend self work
First lets see what extend does.
In the above case
Calculator is extending module
M and hence all the instance methods of module
M are directly available to
In this case
Calculator is a class that exended the module
Calculator does not have to be a class to extend a module.
Now lets try a variation where
Calculator is a module.
Here Calculator is a module that is extending another module.
Now that we understand that a module can extend another module look at the above code and question why module
M is even needed. Why can’t we move the method
double to module Calculator directly. Let’s try that.
I got rid of module
M and moved the method
double inside module
Calculator. Since module
M is gone I changed from
extend M to
One last fix.
Inside the module Calculator what is
self is the module
Calculator itself. So there is no need to repeat
Calculator twice. Here is the final version
Converting A Class into a Module
Everytime I would encounter code like
extend self my brain will pause for a moment. Then I would google for it. Will read about it. Three months later I will repeat the whole process.
The best way to learn it is to use it. So I started looking for a case to use
extend self. It is not a good practice to go hunting for code to apply an idea you have in your mind but here I was trying to learn.
Here is a before snapshot of methods from
Util class I used in a project.
extend self code became
Much better. It makes the intent clear and ,I believe, it is in line with the way ruby would expect us to use.
Another usage inline with how Rails uses extend self
Here I am building an ecommerce application and each new order needs to get a new order number from a third party sales application. The code might look like this. I have omitted the implementation of the methods because they are not relevant to this discussion.
Here the method
next_order_number might be making a complicated call to another sales system. Ideally the class
Order should not expose method
next_order_number . So we can make this method
private but that does not solve the root problem. The problem is that model
Order should not know how the new order number is generated. Well we can move the method
next_order_number to another
Util class but that would create too much distance.
Here is a solution using
Much better. The class Order is not exposing method
next_order_number and this method is right there in the same file. No need to open the
To see practical examples of
extend self please look at Rails source code and search for
extend self. You will find some interesting usage.
This is my first serious attempt to learn usage of
extend self so that next time when I come across such code my brain does not freeze. If you think I have missed out something then do let me know.