Jul 01, 2015
Table of contents:
A problem that you will encounter when you begin to work on bigger Ruby projects is code organisation and how best to reuse code.
Modules are a way of “namespacing” your code. This is important for organisation, but it also prevents name clashes between classes, methods and constants.
In today’s tutorial we’ll be looking at creating and using Modules in Ruby.
Generally speaking, “modularity” is one of the basic qualities of good code, but Modules are also important in Ruby for a number of other concrete reasons.
When you start to work on bigger projects and you pull in Open Source code, you will inevitably find that certain methods or class names are used repeatedly in different contexts.
This causes a problem because the names of classes, methods or constants will clash and override each other.
For example, imagine you wrote a couple of classes for working with the Twitter API. You might have a Client
class that deals with the HTTP requests.
When working on a bigger project, you need to ensure your Client
class does not clash with any other class called Client
.
Namespacing allows you to organise code into protected little buckets to prevent this problem from occurring.
If you’re new to Ruby, thinking about working on bigger projects or using Open Source code might seem like we’re jumping the shark a bit.
However, it’s really easy to define Modules in Ruby, and so it’s a good practice to start early:
module Authentication
end
To define a module, use the module
keyword, give it a name and then finish with an end
.
The module name follows the same rules as class names. The name is a constant and should start with a capital letter. If the module is two words it should be camel case (e.g MyModule).
The first common thing you will see modules used for is to namespace constants:
module Authentication
AUTH_ENDPOINT = 'https://example.com/auth'
end
To use this constant, you simply prefix the module name:
Authentication::AUTH_ENDPOINT
# => "https://example.com/auth"
Next, you can define methods on the module like this:
module Authentication
AUTH_ENDPOINT = 'https://example.com/auth'
def self.configure
# Configure the authentication
end
end
In this example the method is a Class Method (Understanding Class Methods verses Instance Methods in Ruby). Once again to call the method simply prefix the module name:
Authentication.configure
You can also define classes within Modules:
module Authentication
AUTH_ENDPOINT = 'https://example.com/auth'
def self.configure
# Configure the authentication
end
class Http
def self.get(url)
# Make a GET request
end
end
end
To use a module class, you would use the following syntax:
Authentication::Http.get('https://example.com/users')
And finally you can also have modules within modules:
module Authentication
AUTH_ENDPOINT = 'https://example.com/auth'
def self.configure
# Configure the authentication
end
class Http
def self.get
# Make a GET request
end
end
module Serializers
class JsonSerializer
end
end
end
And predictably, you would use it like this.
Authentication::Serializers::JsonSerializer.new
Modules are a very useful part of the Ruby language and you will see them used to great effect within the Ruby community.
Namespacing your code is a good practice you should follow as it makes working within bigger projects much easier.
When you learn a new technique such as this, it’s easy to get carried away and go nuts. Generally speaking you should keep your modules pretty shallow.
In next week’s tutorial we will be continuing with out exploration of Modules to understand another important use-case.