What I didn’t know about Ruby Classes

I’ve always had this feeling that while learning Ruby and Rails, there were tons of little notions that I didn’t really understood. I’m used to write things in order to learn them so here is a series of short articles about what I didn’t know.

The class Class

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

>> Class.superclass
=> Module
>> Module.superclass
=> Object

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

>> Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]

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

Classes are constants

class Foo
end
>> Foo.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 :

Foo = Class.new
>> Foo.class
=> Class

How does Ruby looks for a method ?

class MyExample   
def say_hello
puts 'hello world'
end
end
>> MyExample.ancestors
=> [MyExample, Object, Kernel, BasicObject]
>> MyExample.new.say_hello
=> hello world
>> MyExample.new.say_good_bye
=> NoMethodError

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

Include

module RandomModule
def say_thank_you
puts 'thank you'
end
end
class RandomClass
include RandomModule
end
>> RandomClass.new.say_thank_you
=> thank you
>> RandomClass.ancestors
=> [RandomClass, RandomModule, Object, Kernel, BasicObject]

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

module RandomModule
def say_thank_you
puts 'thank you'
end
end
class RandomClass
extend RandomModule
end
>> RandomClass.new.say_thank_you
=> NoMethodError
>> RandomClass.say_thank_you
=> thank you
>> RandomClass.ancestors
=> [RandomClass, Object, Kernel, BasicObject]

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 :

module RandomModule
def say_thank_you
puts 'thank you'
end
end
class RandomClass
end
>> RandomClass.new.say_thank_you
=> NoMethodError
>> new_instance = RandomClass.new
>> new_instance.extend RandomModule
>> new_instance.say_thank_you
=> thank you

Classes are open

class String
def tell_my_size
self.size
end

def reverse
self.size
end
end
>> my_string = 'hello world'
>> my_string.tell_my_size
=> 11
>> my_string.reverse
=> 11

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’am also the maker of stanza.dev that helps developers to learn coding concepts faster. Feel free to have a look 👨‍💻 👩‍💻

Cheers ✌️

Other stories I’ve written ✍️

What I didn’t know about MIME types

Keep your secret environment variables hidden in Next.js

Written by

Fullstack developer in love with Rails, React and Next.js Maker of stanza.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