Module constructs are cornerstones of the Ruby language,
yet the basic principles of each are often overlooked resulting in incorrect
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
Classand it has no instance methods,
you shouldn't be using a
To illustrate, here is a common example of where people go astray:
Class TaxCalculator def self.calculate(amount) amount * 1.2 end end
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
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 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
calculate directly e.g.
TaxCalculator.calculate. Here are two common
ways to make that a reality:
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
Another way to achieve a similar result is to use
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.