Using modules in Ruby can be very useful for a number of reasons.
- Ruby classes can only have one superclass so modules are a nice way to add functionality to classes without using inheritance
- Modules provide namespaces to prevent name clashes.
Modules as mixins
Ruby does not support multiple inheritance, i.e., each class can only inherit from one superclass. But Ruby modules pretty much eliminate any need for mulitple inheritance by providing what’s known as a mixin. By “mixing in” with your class, modules add powerful functionality.
You can use a module by including it in a class or extending it on an instance of a class. When Ruby goes to look for a method that’s been called, it will look for the method in your superclasses and any modules mixed in to your class or superclasses. Here’s an example of how to include a module:
module NewStudent def introduce puts "Hi, I'm a new student." end end class Student include NewStudent end mike = Student.new mike.introduce #=> "Hi, I'm a new student."
Here’s an example of extending a module:
class Student end mike = Student.new mike.extend(NewStudent) mike.introduce #=> "Hi, I'm a new student."
Modules provide namespaces
You can nest classes inside of modules to keep classes with similar names separate. For example, let’s say you have a student, but one is in college and one is in high school. You could do this:
module College class Student def introduce puts "Hi, I'm a college student." end end end module HighSchool class Student def introduce puts "Hi, I'm a high school student." end end end
Now you can call the introduce method for each of these without clashing names:
mike = College::Student.new sam = HighSchool::Student.new mike.introduce #=> "Hi, I'm a college student." sam.introduce #=> "Hi, I'm a high school student."
This technique with nested module/class chains can help keep classes separate if you really need to have two classes with the same name.
When to use modules
Modules don’t have instance classes. So generally speaking, entities or things are best modeled in classes, and characteristics or properties of entities or things are best captured in modules. Along these lines class names tend to be nouns and module names tend to be adjectives.
Inheritance and modules are closely linked so when deciding between which one to use remember that you can only inherit from ONE class. You don’t want to create a subclass unless an entity will always be a closely-linked entity of its superclass. Modules are much better in situations where you might be able to reuse the methods of the module for a variety of objects, much like many of Ruby’s built-in modules, like Date and Math.