Dramatic Development

Modules vs Inheritance in Ruby

July 11, 2020

I was recently asked in an interview what the difference between modules and inheritance in Ruby is, and when I would use one over the other. I struggled a bit to come up with a clear answer, so I knew it was time to brush up on my Ruby!

Ruby is an Object-Oriented Programming (OOP) language, and classes are the fundamental building blocks of OOP. Classes are blueprints for creating objects, and describe the behavior and properties each instance will have. Let’s say, for example, that I am a person. I am an individual instance of a person, Shane. All people share specific properties, such as having a name, eating, drinking, sleeping, etc. In Ruby, you could say I belong to the Person class, which contains all these shared properties and behaviors. Classes are the re-usable blueprint that let you create each individual instance.

Now, let’s say you have multiple classes that share behaviors. Instead of rewriting all that code in each class, Ruby provides a few ways to create reusable code. In this post I will walk you through two ways to provide reusable behaviors to classes: inheritance and modules.

Inheritance

If you want to create a class which has all of the attributes and methods of another class, but is more specified, you can use inheritance. By inheriting from a parent class, the child class will have access to all behaviors the parent has. For example, a Singer is a more specific version of a Performer, which is a more specific version of a Person. A Performer would inherit all the behavior of a Person, and a Singer would inherit from a Performer. In Ruby, it would look like this:

class Person
end
class Performer < Person
end
class Singer < Performer
end

All methods and properties defined in Person will be available in Singer, but not everything in Singer will be available in Person. The most generic classes live at the top level, and things get more specific as you move down levels. Lets go ahead and build out this classes more to demonstrate.

class Person
def eat
puts "Nom Nom Nom"
end
def drink
puts "Slurp"
end
def sleep
puts "ZZZzzz"
end
end
class Performer < Person
def razzle_dazzle
puts "🎉 🎉 🎉"
end
end
class Singer < Performer
def sing
puts "🎶 La La La 🎶"
end
end

Now, we can create a few instances of these classes and see exactly who has access to which methods.

john = Person.new
hugh = Performer.new
whitney = Singer.new
john.eat # ✅
john.razzle_dazzle # ❌
hugh.razzle_dazzle # ✅
hugh.sing # ❌
whitney.sing # ✅
whitney.razzle_dazzle # ✅
whitney.sleep # ✅

Modules

What if we have a separated set of methods we want to be able to add to any class in any inheritance chain? We can use a module! A module is similar to a class in that it contains methods in order to be re-used. Modules can not be instantiated though, meaning you can not create a new instance using the new method. Modules can be included inside a class, giving that class access to anything contained within the module.

module BreathSupport
def deep_breath
puts "💨"
end
end
class Singer < Performer
include BreathSupport
def sing
puts "🎶 La La La 🎶"
end
end
class Actor < Performer
include BreathSupport
def monologue
puts "To be or not to be... 💀"
end
end
audra = Singer.new
kenneth = Actor.new
audra.deep_breath # ✅
kenneth.deep_breath # ✅

Now any instance created from either the Actor or Singer class will have access to the deep_breath method defined inside the BreathSupport module.

Inheritance vs Modules

So, when should you use a module instead of inheriting from a class? A good rule of thumb is to consider is whether or not you will want to create an instance based on the functionality you desire. If so, you will want to create a class as you cannot create instances of modules. If not, you can likely use a module to accomplish the behavior you want, and it can be included in any classes which require it. Additionally, if you want to create a blueprint that is a more specific version of a class that already exists, including all of the contents of that class, that would be the perfect time to use inheritance.


Congrats!

You now know how to get started working with class inheritance and modules in Ruby, and when you might want to use them. Thank you for reading, and good luck with your projects!


The personal blog of Shane Lonergan. NYC based software engineer, actor, director, and musician. Documenting my journey from the stage to the computer screen. To keep up to date,