arrow flex-icongithublightnings linkedinlock target triangle-icon twitter

Class vs Module in Ruby - Getting it Right

Tom
January 12, 2017

The Class and Module constructs are cornerstones of the Ruby language,
yet the basic principles of each are often overlooked resulting in incorrect
usage.

Cookie Cutting with Classes

In object-oriented programming, a class is an extensible program-code-template
for creating objects, providing initial values for state (member variables)
and implementations of behaviour (member functions or methods).

In short, classes are designed to create objects. The Class provides a
template or cookie cutter for creating instances of itself.

As a rule of thumb, if you create a Class and it has no instance methods,
you shouldn't be using a Class

To illustrate, here is a common example of where people go astray:

Class TaxCalculator
  def self.calculate(amount)
    amount * 1.2
  end
end

The above Class does not manage state and it does not have instance methods
for the objects it creates. The calculate function would be better suited in a
Module.

Modules and Functions

In computer science, functional programming is a programming paradigm — a style
of building the structure and elements of computer programs — that treats
computation as the evaluation of mathematical functions and avoids
changing-state and mutable data.

In functional code, the output value of a function depends only on the
arguments that are input to the function

If you find yourself looking to create a function, which is not specific to an
object, you are best to use a Module.

Module TaxCalculator
  def calculate(amount)
    amount * 1.2
  end
end

Without a bit of extra magic or mixing this module into a Class you can't
access calculate directly e.g. TaxCalculator.calculate. Here are two common
ways to make that a reality:

module_function

Yes, that's right, Ruby has a method module_function, which will allow you to call methods direct on a module, neat.

Module TaxCalculator
  def calculate(amount)
    amount * 1.2
  end
  module_function :calculate
end

extend self

Another way to achieve a similar result is to use extend self:

Module TaxCalculator
  extend self

  def calculate(amount)
    amount * 1.2
  end
end

Although both these approaches will allow you to call your method direct on the Module, there are a couple of subtle differences. That's slightly out of scope for this article, but you can have a further read on the topic here.

Articles

By using this website you agree to our cookie policy
x