What I didn’t know about Ruby Classes

I have been coding with Ruby on rails & React.js for two years now as a professional developer, but I had this feeling that while learning Ruby and Rails, there were tons of little notions that I didn’t really understood. I use to write things in order to learn them so here is a series of short articles about what I didn’t know.

Image for post
Image for post
Sushant Vohra — Unsplash.com

The class Class

The class Class inherits directly from Module, and adds to it all the behavior related to instances. Long story short, Modules are used to add methods to one or several Classes of your app, and Classes are used to managed your objects’ properties.

Image for post
Image for post

Ps: This diagram is very very very minimalist and focus on Class, but Module and Object have a lot of other children.

Classes and ancestors

In order to see the the ancestor of a Class, you can use the .superclass method :

And if you want to see all the superclasses of a particular class, you can use the .ancestors method :

Here, the array includes all the superclasses of Class and this is what we call the ancestor chain in ruby.

Classes are constants

In Ruby, when you define a new class, you are actually creating an instance of the class Class.

For example, here, we have just created a new class named Foo, which is an instance of the class Class and we can access to this instance by using the contant Foo.
Following this logic, we can see that we could have created Foo like a casual object :

How does Ruby looks for a method ?

say_hello : When we call the say_hello method on an instance of the MyExample class, Ruby looks through the MyExample class for a method named say_hello, it finds it and return the appropriate result.

say_good_bye : If I call a say_good_bye method, ruby will look into MyExample for this method, it will not find it and then it will goes through the ancestor chain passing through each parent at a time until BasicObject to find a method called say_good_bye.

Because the say_good_bye method doesn’t exist in the MyExample class or any of the ancestors, Ruby will return a NoMethodError.

Include and Extend your Classes

Adding a Module’s code to a Class can be done using the include, extend and prepend methods. Let’s focus on the two firsts as they are much more commons.

Include

As the doc says When a class includes a module, module’s instance methods become available as instance methods of the class.

Here you can also see that if we check the ancestor chain of our RandomClass, the RandomModule appears !

As we saw earlier, when we call the module’s method (say_thank_you), Ruby will check in our RandomClass class for the method, it will not find it so Ruby will go through each of the ancestors of the RandomClass class in order to find the method.

Extend

I’ve always found obscure the difference between extend and include, but they are actually very different : extend adds the module’s method as class methods and not instance methods.

As you can see, the module is mixed with our RandomClass, and it’s methods are not accessible at the instance level (RandomClass.new.method) but at the class level (RandomClass.method).

You can even use extend on one particular instance :

Classes are open

It means that you can always add and edit methods of a particular ancestor class. You can do it for classes that you have created yourself or even from classes which are part of Ruby.

We have added a new method to the String class and we have changed the behavior of the reverse method.
Note that it is of course dangerous to override other Classes this way ! Be very careful by doing so and always prefer to edit the existing classes directly.

The last word

I know there are lots of other concepts around Classes but that’s all for this article, feel free to improve my explanation in the comments, I might add more concepts here in the future 👋

Written by

Fullstack developer Rails / React.js https://olivierdumas.dev/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store