## DEV Community is a community of 616,519 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Using Modules in Ruby

Merdan Durdiyev ・5 min read

Welcome back dear friends, dear readers, coders, and enthusiasts!

Welcome to our next article where we present the preciousness of our beloved Ruby PL. This time we are going to look through the “Modules” topic in Ruby. We will also strengthen our learning by showing some examples of how to use Modules in Ruby.

....................................................

# What are the Modules?

In short, a Module is a way to gather classes, methods, and constants under one roof. To expand the topic a bit wider, this gives us two widely used methodologies in programming.

1. Collectionotherwise named as a ‘namespace’, gives us an opportunity to gather classes, methods, and constants under a single roof.

2. Mixina mechanism to include a ready module into another class and use its content (methods, values, constants) as its own. Thus we can expand the possibilities of that class.

After mentioning its advantages in general, let’s dive deeper into it and look at the above-mentioned items in detail. We will also provide explanations with code examples where possible.

....................................................

# 1. Collection

Imagine such a situation. You decided to collect together operators, functions, and all the related data into one place. Why should we not make it a module?

``````module Trig
PI = 3.1416 # A Constant

Trig.sin(x)
#...
end

Trig.cos(x)
#...
end
...
...
end
``````

We can use the above-defined methods and constants somewhere else. Let’s use this module to perform trigonometric calculations. Here is an example:

``````radius = 6

# Here we call a constant named 'PI' from module 'Trig'
area = Trig.PI*radius**2 # PI*R^2 formula

# Let's calculate sine and cosine of the angle.
# Here we call 'sin' and 'cos' methods from
# 'Trig' module.

angle = 45
sine = Trig.sin(angle)
cosine = Trig.cos(angle)
``````

If these examples are a bit easy for you, we can take a look at more complex ones. Now, let’s take a look at a module that comprises several classes in it.

You decided to develop a ‘Customer’ class. It has a few properties and methods. Depending on the context, a customer can act differently. So let’s write a class that has a bit different methods and properties depending on the type of customer in a particular situation, and place them in different modules.

``````module Bank
class Customer # A bank customer.
attr_accessor :balance, first_name, last_name

def put_cash(sum)
puts "#{sum} amount of cash was put."
end

def withdraw(sum)
puts "#{sum} amount was withdrawn."
end
end
end

module Shop
class Customer # A shop customer
attr_accessor :products

def pay_for_products
products.each do |product|
puts "#{product} bought."
end
end
...
...
end
end
``````

I hope you paid attention to how we separated the issues and placed two different customers in two different modules. Both of the modules have ‘Customer’ class, but they behave differently. In other words, they have different methods and properties. If we have defined both classes in the same namespace, we would have had a conflict. And that would be a name conflict at least, not to mention the others. Ruby would not have allowed us to write the same-named class within the same namespace. So we just place them in different modules and no conflicts comes up.

Now we can easily call and use the ‘Customer’ class and its methods in the following examples:

``````# Example - 1
bank_customer = Bank::Customer.new
bank_customer.balance = 25
bank_customer.first_name = "John"
bank_customer.last_name = "Brown"
bank_customer.withdraw(50)

# Example - 2
shop_customer = Dukan::Customer.new
shop_customer.products = ["apple", "fig", "bread", "milk"]
shop_customer.pay_for_products
``````

As you see in the examples above, by placing classes, modules, and constants into different modules we can avoid name conflicts and have them being used within the right context.

Now let’s take a look at how we can use them as Mixins.

...................................................

# 2. Mixins

### Example A : Class relationships

There is a bit complex relationship matter called ‘inheritance’ in the programming world. It is a case when a class is a child/subclass of another one, that we call as ‘parent’. This way a child class possesses the features and methods of a parent class. Here is an example of this:

``````# Define a class for animals.
class Animal
attr_accessor :name, :category

def make_noise
puts 'Making noise...'
end

def move
puts 'Moving...'
end
end
``````

The next classes to be defined are somewhat part of, or subpart of an ‘Animal’ class. And they will possess the features and methods of an ‘Animal’ class. So, let’s define classes ‘Fish’ and ‘Bird’ and make them as child classes of an ‘Animal’ class. ‘Ruby’ PL makes it this way:

``````# 'Fish' class
class Fish < Animal
...
end

# 'Bird' class
class Bird < Animal
...
end
``````

Now we can call methods of an ‘Animal’ class and use its properties from within ‘Fish’ and ‘Bird’ classes.

``````a_fish = Fish.new
a_fish.name = 'Ariel'
a_fish.make_noise # 'Making noise...'

a_bird = Bird.new
a_bird.name = 'Dove'
a_bird.move # 'Moving...'
``````

### Example B : Mixins

Now, getting inspired by the examples above, let’s write something a bit different. A film, an advertisement, a clip are all Videos. We can ‘play’ them and ‘pause’ them all.

Besides that, we can download them onto our PC or mobile device. Suppose we can download only video, only audio, or both at the same time. We have ‘Download’ module for this.

So let’s define ‘Video’ and ‘Download’ modules for this purpose.

``````# 'Video' module
module Video
def play
puts 'Playing ...'
end

def pause
puts 'Paused...'
end
end

end

end

end
end
``````

Now let’s define other 3 classes and make methods of ‘Video’ and ‘Download’ modules available to them.

``````# 'Film' class
class Film
attr_accessor :title
include Video
end

include Video
end

# 'Clip' class
class Clip
include Video
end
``````

Now we can use features of ‘Video’ and ‘Download’ modules after making them available within those lately defined classes. Here is an example:

``````# 'Film' class
silence = Film.new
silence.title= 'The Silence of Lambs'
silence.play  # 'Playing ...'

cola_ad.play  # 'Playing ...'

# 'Clip' class
drake_clip = Clip.new
drake_clip.play  # 'Playing ...'
``````

So we defined ‘Video’ and ‘Download’ as modules, and not classes. Lately, we made their features available to the other three classes. We used ‘include’ keyword for that.

### Differences between Example A and Example B

The relationship between a Parent and a Child class is very important in programming. We implement it with a mechanism called ‘inheritance’ and avoid writing excess code. Thus we support DRY (Don’t Repeat Yourself).

Both ‘A’ and ‘B’ examples are doing almost the same thing but there are few differences between them. A Ruby class can not inherit from multiple classes at the same time. In other words, a class can not have multiple parent classes at the same time. So we could not inherit from ‘Video’ and ‘Download’ classes at the same time. For this reason, we implemented ‘Video’ and ‘Download’ as modules and used them as Mixins in ‘Film’, ‘Advertisement’, and ‘Clip’ classes.

.................................................

# Conclusion

And now, we introduced our beloved Ruby PL closer and learned how to implement Modules in it. Besides that, we learned in which cases we should implement something as a Class or as a Module.

One of the famous modules in Ruby PL are ‘Enumerable’ and ‘Comparable’ modules. By including these modules into your custom classes, you add comparison and numerating functionality to your own classes. This way you can compare two instances of your own class and iterate through its elements if it is a type of collection.

Hope to meet you soon in the next article, dear friends.
Stay healthy, wealthy, and wise!