March 18, 2021

How To Make Your First Ruby Gem (a step-by-step guide)

It could be argued that most developers who have worked with ruby on rails, might be interested in developing a specific gem to solve problems for their fellow developers.

However, it's not uncommon for developers to not know where to begin, or to not know where a gem is created in the first place. It's also not uncommon for a developer to feel like this could be a difficult and complicated task.

For that reason, the aim of this article is to explain how to develop your first gem, and also take a look at the different components involved when doing so.

Here at Rootstrap, we are very interested in being part of the open-source world. For that reason, we have been working on this topic for some time, by making libraries for different languages/frameworks, and also making them visible to the public.

For example, we made rsgem, a gem that allows you to generate a base project to create a gem, on which this article is based.

Starting The Gem

The first step here is to install the rsgem by running [.c-inline-code]$ gem install rsgem[.c-inline-code]. Once the gem is installed, we have to run [.c-inline-code]$ rsgem new [name][.c-inline-code], with the name that we want for our gem included.

In this blog post, we will pay close attention to running the command [.c-inline-code]$ rsgem new blog_gem[.c-inline-code], as this will generate a project structure.

It's important to mention that the gem rsgem is based on the command 'bundle gem', as it is the command that generates the directories, and the files that are on display. So, we will look at the different components that are generated for the gem that we want to create.

Bin Folder

In the Bin folder, we will find the console and setup files. The important thing here is to highlight the utility of the console file, where we can see the next code:

#!/usr/bin/env ruby

require 'bundler/setup'
require 'blog_gem'

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require 'irb'

If we have to test from the terminal with our gem, we just need the command bundle console 'require_name', to access the interactive ruby shell with each of our methods, and also the dependencies of the gem. In our gem example, we just need to include a bundle console blog_gem.

Lib Folder

The Lib folder is where the magic happens, as it is where we put the classes, codes, and methods, that will be on offer to the developers when using our gem.

If you look closely, you will see a folder with the name of our gem, and if you look inside the folder, you will find a file with the name version.

This version file is used to indicate the current version of our gem, and will also be used to complete the version attribute of our gemspec file, which we will see later.

As well as this, we have the file name_gem.rb (in our example 'blog_gem.rb'), which is the main file of the gem. This file contains specific code similar to the following:

require 'blog_gem/version'

module BlogGem
  class Error < StandardError; end
  # Your code goes here...

As we can see here, it is a class wherein principle, you could put the code directly in. That decision is up to the developer, but generally, there won't be code added to this file.

Instead of this, 'requires' will be added to the files, which contain the classes that offer the methods of our gem. We can also see that this class covers generic error handling, which follows the ruby guidelines.

Spec Folder

In the world of software development, it's understood that good software always has to have unit tests that support the implemented code. For this very reason, here at Rootstrap, we use RSpec.

Our test files must be put in the spec folder, as this will allow us to implement the unit tests of our gem, which we can execute from the console with the RSpec command.

Gemspec File

require_relative 'lib/blog_gem/version' do |spec|          = 'blog_gem'
  spec.version       = BlogGem::VERSION
  spec.authors       = ['TimoPeraza']         = ['']

  spec.summary       = ''
  spec.description   = ''
  spec.homepage      = ''
  spec.license       = 'MIT'
  spec.required_ruby_version ='>= 2.3.0')

  # spec.metadata["allowed_push_host"] = "TODO: Set to ''"

  # spec.metadata["homepage_uri"] = spec.homepage
  # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's URL here."

  # Specify which files should be added to the gem when it is released.
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
  spec.files = Dir['LICENSE.txt', '', 'lib/**/*']
  spec.bindir        = 'exe'
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ['lib']
  spec.add_development_dependency 'rake'
  spec.add_development_dependency 'reek'
  spec.add_development_dependency 'rspec'
  spec.add_development_dependency 'rubocop'
  spec.add_development_dependency 'simplecov', '~> 0.17.1'

In this file, we will put all the information for our gem, i.e. who made it, contact email, description, and the version. This file will also contain the files that allow the gem to do a release and the external dependencies with which the gem needs.

By default, Rsgem adds the following dev dependencies: Rake, Reek, RSpec, Rubocop, and Simplecov. We do this because we like to focus on the qualify of the code, and as a result, we add these dependencies to ensure our gem has the highest quality possible.

Readme File

Finally, in the Readme file, we will need to add all of the information associated with our gem. For example, how it works, how to install it, the methods that it offers, as well as anything that could be useful for a developer to use.

What To Take Away

Now that you have a general idea of the components contained in a project, you are ready to get down to work and develop your first gem!

For more information about how to do this, I strongly recommend looking at the following page rubygems.

Thank you for taking the time to read this blog post and hopefully you will be able to use this information to your advantage.