Question

Ruby Modules vs Classes: What’s the Difference and When to Use Each?

rubyclassmodule

Question

I recently moved from Java to Ruby, and one language feature I am not yet familiar with is the module.

What exactly is a module in Ruby? When should you use a module, and why would you choose a module instead of a class?

Short Answer

By the end of this page, you will understand what Ruby modules are, how they differ from classes, and the two main reasons developers use them: sharing behavior and organizing code with namespaces. You will also see when a class is the right choice, when a module is better, and how both are often used together in real Ruby codebases.

Concept

In Ruby, a class and a module are both ways to group code, but they serve different purposes.

A class is mainly used to create objects. It acts like a blueprint for instances:

class User
  def initialize(name)
    @name = name
  end
end

user = User.new("Ava")

A module cannot be instantiated. You cannot call .new on a module. Instead, modules are mainly used for two things:

  1. Mixing in shared behavior
  2. Creating namespaces

1. Shared behavior

A module can contain methods that multiple classes can reuse.

module Speakable
  def speak
    "Hello"
  end
end

class Person
  include Speakable
end

class Robot
  include Speakable
end

Now both Person and Robot have a speak method, without needing inheritance between them.

2. Namespaces

A module can group related classes and constants to avoid name conflicts.

module Payments
  class Processor
  end
end

module Admin
  class Processor
  end
end

Here, Payments::Processor and Admin::Processor are two different classes with the same class name.

Why this matters

If Ruby only had classes, developers might overuse inheritance just to share methods. Modules give Ruby a more flexible way to reuse code without forcing an “is-a” relationship.

For example:

  • A Dog is a Animal → inheritance may make sense.
  • A Dog can be trained and can be tracked → modules may make more sense.

So the key idea is:

  • Use a class for objects and state.
  • Use a module for shared behavior and namespacing.

Mental Model

Think of a class as a factory blueprint and a module as a toolbox or a folder.

  • A class is a blueprint that lets you build objects.
  • A module is a toolbox of methods you can attach to classes, or a folder that keeps related code together.

Toolbox analogy

Imagine several workers:

  • A carpenter
  • An electrician
  • A plumber

They are different types of workers, so they should not all inherit from one another. But they may all use the same safety procedures. Instead of forcing them into a strange inheritance chain, you put those shared procedures in a module and include it where needed.

Folder analogy

Now imagine you have files named Report in different departments:

  • Sales::Report
  • Finance::Report

The module acts like a folder name that keeps things organized and prevents collisions.

That is the mental model:

  • Class = blueprint for making things
  • Module = shared toolbox or organizing folder
Take Quiz

Syntax and Examples

Basic class syntax

class User
  def initialize(name)
    @name = name
  end

  def greeting
    "Hello, #{@name}!"
  end
end

user = User.new("Mina")
puts user.greeting

A class:

  • can be instantiated with .new
  • can store instance data in variables like @name
  • is used to model objects

Basic module syntax

module Greeting
  def say_hello
    "Hello!"
  end
end

A module:

  • cannot be instantiated
  • is often included in classes
  • is useful for shared methods or namespacing

Using a module with include

module Greeting
  def say_hello
    "Hello!"
  end
end

class Person
  include Greeting
end

person = Person.new
puts person.say_hello

include Greeting adds the module's instance methods to the class.

Using a module as a namespace

module Payments
  class Invoice
    def total
      100
    end
  end
end

invoice = Payments::Invoice.new
puts invoice.total

Here, the module is not being mixed in. It is just grouping related code.

Module methods

Sometimes a module is used to hold utility methods.

module MathHelper
  def self.double(number)
    number * 2
  end
end

puts MathHelper.double(5)

This is common for helper-style logic that does not belong to a particular object.

Step by Step Execution

Consider this example:

module Walkable
  def walk
    "Walking"
  end
end

class Person
  include Walkable
end

person = Person.new
puts person.walk

Step-by-step

  1. Ruby reads the Walkable module.
  2. Inside the module, it finds a method called walk.
  3. Ruby reads the Person class.
  4. include Walkable tells Ruby to make the module's instance methods available in Person.
  5. Person.new creates a new Person object.
  6. person.walk is called.
  7. Ruby looks for walk on the Person instance.
  8. It does not find walk directly in the class, so it checks included modules.
  9. It finds walk in Walkable.
  10. The method runs and returns "Walking".

Important takeaway

The Person object behaves as if it has a walk method, but that method actually came from the module. This is code reuse without forcing Person to inherit from another class just to get one method.

Real World Use Cases

1. Sharing common behavior across unrelated classes

module Timestamped
  def formatted_time
    Time.now.strftime("%Y-%m-%d")
  end
end

class Order
  include Timestamped
end

class Message
  include Timestamped
end

Order and Message are different concepts, but both can reuse the same behavior.

2. Organizing large applications with namespaces

module Api
  class Client
  end
end

module Admin
  class Client
  end
end

This avoids naming conflicts in bigger systems.

3. Utility or helper functions

module Formatter
  def self.currency(amount)
    "$%.2f" % amount
  end
end

Useful for formatting, parsing, configuration helpers, and small reusable utilities.

4. Framework mixins

Ruby frameworks often use modules heavily.

Examples include:

  • validation behavior
  • authentication helpers
  • logging methods
  • serialization methods

A class can include only the behaviors it needs.

5. Grouping domain code

module Billing
  class Invoice
  end

  class Receipt
  end
end

This makes a codebase easier to navigate because related classes live under one namespace.

Take Quiz

Real Codebase Usage

In real Ruby projects, modules are used in a few common patterns.

Mixins for shared behavior

Developers place reusable methods in modules and include them in multiple classes.

module Loggable
  def log(message)
    puts "[LOG] #{message}"
  end
end

class OrderProcessor
  include Loggable

  def process
    log("Processing order")
  end
end

This avoids duplication and avoids unnecessary inheritance.

Namespacing application areas

Large apps often group code by feature or domain.

module Payments
  class ChargeService
  end

  class RefundService
  end
end

This makes class names clearer and keeps related code together.

Guard clauses and shared checks

Modules often hold reusable validation or authorization logic.

module AdminOnly
  def ensure_admin(user)
    raise "Access denied" unless user.admin?
  end
end

Classes that need the same rule can include the module.

Extending classes with class-level behavior

Ruby also allows modules to add class methods.

module Findable
  def find(id)
    "Finding record #{id}"
  end
end

class User
  extend Findable
end

puts User.find(10)
  • include adds instance methods
  • extend adds methods to the object itself, often class methods when used inside a class

Concern-style organization

In Rails projects, developers often use modules to extract repeated logic into concerns, such as:

  • Publishable
  • Searchable
  • Archivable

These names usually describe a capability, not a type. That is a good sign that a module may be appropriate.

Common Mistakes

1. Trying to instantiate a module

Broken code:

module Helper
end

helper = Helper.new

This fails because modules cannot be created with .new.

Use a class if you need instances:

class Helper
end

helper = Helper.new

2. Using inheritance when a module is a better fit

Broken design:

class Animal
  def log
    puts "Logging"
  end
end

class Car < Animal
end

A Car is not an Animal. This inheritance relationship is wrong.

Better:

module Loggable
  def log
    puts "Logging"
  end
end

class Car
  include Loggable
end

3. Confusing include and extend

module Greeting
  def hello
    "Hello"
  end
end

class Person
  include Greeting
end

Person.hello

This fails because include adds an instance method, not a class method.

Correct usage:

person = Person.new
puts person.hello

Or use extend if you want a class-level method:

class Person
  extend Greeting
end

puts Person.hello

4. Putting too much unrelated code in one module

A module should represent one clear responsibility.

Bad example:

module Utils
  def format_price; end
  def send_email; end
  def resize_image; end
end

This becomes hard to understand and maintain.

Prefer smaller, focused modules.

5. Forgetting that modules do not hold per-instance state the way classes do

Modules can define methods that use instance variables, but the actual state belongs to the object that includes the module.

module Named
  def name
    @name
  end
end

This works only if the including class sets @name somewhere.

Comparisons

FeatureClassModule
Can create objects with .newYesNo
Can hold instance methodsYesYes
Can be used for inheritanceYesNo direct instantiation/inheritance role like classes
Can be included in classesNoYes
Can be used as a namespaceYes, but less commonlyYes, very commonly
Best forModeling objectsSharing behavior and organizing code

Class vs module in plain language

  • Use a class when you are defining a thing that will have objects.
  • Use a module when you want to share abilities or group related code.

Inheritance vs mixins

ApproachBest whenExample
InheritanceThere is a true "is-a" relationshipDog < Animal
Module mixinThere is a shared capabilityDog includes Trainable

include vs extend

KeywordWhat it addsExample result
includeInstance methodsPerson.new.hello
extendMethods on the object itselfPerson.hello
Take Quiz

Cheat Sheet

Quick rules

  • Class: use to create objects
  • Module: use to share behavior or create namespaces
  • Modules cannot be instantiated with .new
  • Use include to add module methods as instance methods
  • Use extend to add module methods as class-level methods on the receiving object

Basic syntax

class User
end

module Greeting
  def hello
    "Hello"
  end
end

Include a module

class Person
  include Greeting
end

Person.new.hello

Extend a class with module methods

class Person
  extend Greeting
end

Person.hello

Namespace syntax

module Payments
  class Invoice
  end
end

Payments::Invoice.new

When to choose which

  • Choose class for objects with identity and state
  • Choose module for reusable methods across classes
  • Choose module for organizing related classes/constants

Common edge cases

  • A module can define methods that use instance variables, but the variables belong to the including object
  • Avoid using modules as random containers for unrelated utility code
  • Prefer modules over inheritance when you are sharing a capability, not modeling a type hierarchy

FAQ

What is the main difference between a Ruby class and a module?

A class is used to create objects, while a module is used to share behavior or organize code with namespaces.

Can a module have methods in Ruby?

Yes. A module can define methods that are mixed into classes with include, or used as module-level methods with self.method_name.

Why use a module instead of inheritance in Ruby?

Use a module when multiple classes share a capability but do not have an "is-a" relationship. This avoids incorrect inheritance hierarchies.

Can you create an instance of a module?

No. Modules cannot be instantiated with .new.

When should I use include vs extend?

Use include for instance methods and extend for methods on the receiving object, often class methods.

Are modules only for helper methods?

No. They are also widely used for namespacing and organizing large codebases.

Can a class use more than one module?

Yes. A class can include multiple modules, which is one reason modules are so useful for combining behaviors.

Take Quiz

Mini Project

Description

Build a small Ruby example for a publishing system. You will model content like articles and videos using classes, then use modules to share common behavior such as publishing and to organize the code inside a namespace. This demonstrates the two most important uses of modules: mixins and namespacing.

Goal

Create namespaced content classes that reuse shared publishing behavior through a module.

Requirements

Requirement 1 Requirement 2 Requirement 3

Take Quiz

Keep learning

Related questions

View more