Ruby Module

A Ruby module is a container for grouping related methods, constants, and classes. It can be stored in a file and reused across multiple Ruby programs.

For example, suppose we have two .rb files: math_utilities.rb and main.rb:

  • In math_utilities.rb, we define and expose a method to compute the square of a number.
  • Then, in main.rb, we load that module and use the square function.

Here, math_utilities.rb defines a module that can be reused elsewhere.

Don't worry if you don't understand this yet. We will learn about these in detail below.


Ruby Modules

Let's consider the two .rb files we discussed previously: math_utilities.rb and main.rb.

math_utilities.rb (The Module)

This file defines a module by grouping related methods and making it available for use by other files. It contains the following:

module MathTools
    # Function that calculates square of a number
    def self.square(number)
      number * number
    end
end

Notice that we have defined a method using self. to make it accessible as a module method.

main.rb (Using the Module)

This file uses the function defined in the math_utilities.rb module. Inside the main.rb file, we import the square function as:

# Import the MathTools module from math_utilities.rb
require_relative 'math_utilities'

# Use the imported method to compute the square
puts MathTools.square(4)  # Output: 16

Here, we have used require_relative to load the module and accessed the square method using MathTools.square.

Note: require_relative loads a file relative to the current file. It's commonly used to include modules defined in other files.


Constants in Modules

Modules can also hold constants. These are accessed using the following syntax:

ModuleName::CONSTANT_NAME

Let's see an example,

module AppInfo
  VERSION = "1.0.0"
end

puts AppInfo::VERSION  # Output: 1.0.0

Note: Constants are useful for storing configuration, settings, or fixed values.


Defining Multiple Members in a Module

It is also possible to define multiple members (methods or constants) in a module. For example,

In the file math_utilities.rb,

module MathTools
    PI = 3.14159

    def self.square(number)
      number * number
    end
end

In main.rb file,

require_relative 'math_utilities'

puts MathTools::PI              # Output: 3.14159
puts MathTools.square(6)        # Output: 36

Here,

  • PI is a constant.
  • square is a module method.
  • Both are accessed using the module name.

Using include to Add Instance Methods

You can use include to make module methods available as instance methods in a class. For example,

module Greet
    def say_hello
      "Hello!"
    end
end

class User
    include Greet
end

user = User.new
puts user.say_hello  

Output

Hello!

Here, include mixes the module's methods into the class as if they were written directly in it.


Using extend to Add Class Methods

To use module methods as class methods, you can use extend. For example,

module Greet
    def say_hi
      "Hi!"
    end
end

class Admin
    extend Greet
end

puts Admin.say_hi 

Output

Hi!

Here, extend adds the module's methods to the class itself, so they become class methods.


Using prepend to Override Class Methods

You can use prepend to override class methods with module methods. For example,

module Logger
    def log
        "From module"
    end
end

class Service
    def log
        "From class"
    end
end

class App < Service
    prepend Logger
end

puts App.new.log  

Output

From module

Here, prepend places the module before the class in the method lookup chain, so the module's log method overrides the one in the class.


Avoiding Naming Conflicts Using Namespaces

If different modules define methods or classes with the same name, Ruby allows namespacing to avoid conflicts. For example,

module Admin
    class User
      def role
        "admin"
      end
    end
end

module Guest
    class User
      def role
        "guest"
      end
    end
end

puts Admin::User.new.role  
puts Guest::User.new.role 

Output

admin
guest

Here, the User class exists inside both Admin and Guest modules, but there's no conflict because of namespacing.


More on Ruby Module

Benefits of Using Modules

Some of the benefits of using modules are:

  • Improved Maintainability: Code is organized into separate files based on functionality, making it easier to manage and update.
  • Enhanced Reusability: Modules are designed to be reusable, allowing you to define functionality once and use it across multiple parts of your application or in different projects.
  • Clear Dependencies: By using imports and exports, modules clearly outline their dependencies, thus simplifying debugging and testing.
Including Multiple Modules in a Class

You can include as many modules as needed in a class. For example,

module A
    def greet
        "Hi from A"
    end
end

module B
    def bye
        "Bye from B"
    end
end

class Person
    include A
    include B
end

p = Person.new
puts p.greet   # Output: Hi from A
puts p.bye     # Output: Bye from B

This allows the Person class to use methods from both modules as if they were defined directly inside it.

Module Including Another Module

Modules can include other modules to share behavior. For example,

module A
  def greet
    "Hello"
  end
end

module B
  include A
end

class MyClass
  include B
end

puts MyClass.new.greet  # Output: Hello

This allows Module B (and anything that includes B) to also gain methods from Module A.


Did you find this article helpful?

Your path to become a builder.

Builders don’t just know how to code, they create solutions that matter. Escape tutorial hell and ship real projects.

Try Programiz PRO
  • Real-World Projects
  • On-Demand Learning
  • AI Mentor
  • Builder Community