How Do I Create And Publish My First Ruby Gem?

What’s a Ruby Gem?

To solve various problems with Ruby, you might develop your own libraries. Also, you might want to open-source your libraries to get help from the Ruby community and have many developers working on the same.

A gem is a packaged Ruby application or library. RubyGems is the standard way to distribute Ruby applications and libraries and is available to you after you have downloaded and installed Ruby.

Let us create a simple Ruby library

Let’s first create a simple, trivial gem which I shall call my_string_extend_smt.

Please refer to the note on “How to Name Gems”1. Observe that at the end of the gem name, I have added smt which are my initials. We would want to name the Ruby gem this way, so that it is unique on RubyGems.org.

Our library will extend the String class and we shall store this in a file called my_string_extend_smt.rb in the folder my_string_extend_smt/lib. The lib folder will contain the Ruby code related to the library, namely:

# my_string_extend_smt.rb
class String
  def writesize
    self.size
  end
end

The library opens up the String class and adds a method writesize (which returns the size of the string).

For open-source applications, the gem server to use for your applications is the one provided at https://rubygems.org/. This is where users will look, and is where gem will also look by default when you issue a gem install command. Please make sure that the name of your gem isn’t in use already. Type:

$ gem list -r my_string_extend_smt

*** REMOTE GEMS ***

Observe that no gem of the name my_string_extend_smt exists. We are safe! Now let us now turn our library into a gem, so that one can use it anywhere.

Steps for publishing our gem

1. Update to the latest RubyGem – In the folder my_string_extend_smt open a command window and type:

$ gem update --system

2. Create an account on RubyGems.org – http://rubygems.org/sign_up and confirm your email. Later on, you’ll need to provide your login credentials the first time you push a gem to the server.

3. Create a Gem Specification – In the folder my_string_extend_smt copy the following file my_string_extend_smt.gemspec and edit it as per your needs:

Gem::Specification.new do |s|
  s.name        = "my_string_extend_smt"
  s.version     = "0.0.1"
  s.summary     = "String Extend"
  s.date        = "2013-02-18"
  s.description = "The library opens up the String class and adds a method writesize, which returns the size of the string."
  s.authors     = ["Satish Talim"]
  s.email       = ["satish@rubylearning.org"]
  s.homepage    = "http://rubylearning.org/"
  s.files       = ["lib/my_string_extend_smt.rb"]
end

The gemspec defines what’s in the gem, who made it, and the version of the gem. The gemspec is a chunk of Ruby code that the gem command will read and execute to understand our app, such as its name, files, and dependencies. It’s also our interface to RubyGems.org, all the information you see on a gem page comes from the gemspec.

A gemspec consists of several attributes. Some of these are required; most of them are optional. The required attributes are: name, version, summary, require_paths (default = ["lib"]) and rubygems_version (do not set this; it is set automatically when the gem is packaged).

The details of the attributes used in our gemspec, is available here.

4. Once we have our gemspec, we have to build a gem from it. In the folder my_string_extend_smt type:

$ gem build my_string_extend_smt.gemspec
  Successfully built RubyGem
  Name: my_string_extend_smt
  Version: 0.0.1
  File: my_string_extend_smt-0.0.1.gem

We can then install it locally to test it out:

$ gem install my_string_extend_smt-0.0.1.gem
Successfully installed my_string_extend_smt-0.0.1
1 gem installed
Installing ri documentation for my_string_extend_smt-0.0.1...
Installing RDoc documentation for my_string_extend_smt-0.0.1...

Lets require our gem and use it:

$ irb --simple-prompt
>> require 'my_string_extend_smt'
=> true
>> puts "Hello".writesize
5
=> nil
>> quit

5. Now publish our gem out to RubyGems.org. In the folder my_string_extend_smt type:

$ gem push my_string_extend_smt-0.0.1.gem
Enter your RubyGems.org credentials.
Don't have an account yet? Create one at http://rubygems.org/sign_up
   Email:   satish@rubylearning.org
Password:

Pushing gem to https://rubygems.org...
Signed in.
Pushing gem to https://rubygems.org...
Successfully registered gem: my_string_extend_smt (0.0.1)

In just a few moments (usually a minute), your gem will be available for installation by anyone:

$ gem list -r my_string_extend_smt

*** REMOTE GEMS ***

my_string_extend_smt (0.0.1)

Here’s our Ruby gem on the RubyGems.org site

Rack App
Our Ruby Gem

Deleting your gem at Rubygems.org

Since our gem is for demonstration purposes only, I would like to delete my gem from RubyGems.org’s index. To remove your gem please use the following reference. I removed an old gem of mine my_string_extend of version 0.0.1 as follows:

I installed gemcutter only once by typing:

$ gem install gemcutter

I then removed my old gem by typing:

$ gem yank my_string_extend -v 0.0.1
Yanking gem from RubyGems.org...
Pushing gem to https://rubygems.org...
Successfully yanked gem: my_string_extend (0.0.1)

However, the gem is still available for download for two main reasons:

  1. Other gems may have been pushed that depend on your gem.
  2. A mass deletion of important community based gems can be easily prevented.

That’s it.

Credits: This article has been adopted from Nick Quaranto’s article on RubyLearning – Gem Sawyer, Modern Day Ruby Warrior. RubyGems further adopted this article – Make your own gem.

is an author and founder of RubyLearning.com and RubyLearning.org where 1000s of participants have learnt Ruby programming from across the globe.

Posted by Satish Talim

{ 13 comments… read them below or add one }

Brooke Kuhlmann October 27, 2011 at 6:25 pm

Good write-up. I’d like to point out that if you want to auto-generate, essentially, the same skeleton as constructed by hand above, don’t forget that the Bundler gem gives this to you by simply typing:

bundle gem (name of your gem)

Even better, Bundler then gives you the following Rake tasks for managing your gem:

rake build # Build -.gem into the pkg directory
rake install # Build and install -.gem into system gems
rake release # Create tag v0.1.1 and build and push -.gem to Rubygems

Lastly, if you want to capitalize on Bundler and build more complex gems (using the Bundler philosophy), my Gemsmith gem builder might be of interest (https://github.com/bkuhlmann/gemsmith).

Anyway, food for thought.

Reply

Dan October 27, 2011 at 7:28 pm

Nicely written article ;)

I second what Brooke said, Bundler is really nice for generating a nice clean layout for a gem.

Reply

Victor Goff October 28, 2011 at 8:43 am

Bundler does a good job, as well as Jeweller and Gemcutter.

It is good to know how to do so without the crutches though, so that if something does go wrong you can understand it. And also notice and appreciate the time saved and convenience of Bundler, or Jeweller or Gemcutter (or any other tool).

Reply

Manimaran Malaichamy October 28, 2011 at 10:25 am

Very useful article.

It gives me a clear idea on how to create gems, where to submit and hot to make it use of
others.

Thanks for this nicely written one.

Reply

Joe October 31, 2011 at 5:53 am

This is a great post. Bookmarking for future reference. I had no idea it was quite so easy to share my libraries!

Reply

Sudhir Singh Tomar February 3, 2012 at 4:53 pm

Hi Satish Talim,

This is great post and i usually read your blog that all nice. after read this post i created one normal “hello world”gem but now i want to expand the functionality of my gem like i want to add application it’s having controller model and view. so please help me satish how can i do.
thnaks in advance.

Reply

Satish Talim February 3, 2012 at 5:05 pm
davidcbe June 21, 2012 at 4:01 pm

Hi,

I am able to unpack the gem ‘herubyracer-0.10.1.gem’ using this command

gem unpack therubyracer-0.10.1.gem

I am getting therubyracer-0.10.1 folder
The folder inside (Changelog.md Gemfile README.md Rakefile bin/ ext/ lib/ spec/ specmem/ specthread/ therubyracer.gemspec) file is there.

and I have copied the v8.so file to /lib to lib/v8/ directory

next I have build the gem using

gem build therubyracer.gemspec

The gem is build, getting (therubyracer-0.10.1.gem)

I have unpack the gem (therubyracer-0.10.1.gem) only ext and lib folder are there, there is no bin and other folders.

Please let me know, how can i make the gem included (I have copied the v8.so file to /lib other directory) change.

Thanks for advance.

David

Reply

Victor Goff July 6, 2012 at 6:34 am

Check the original repository, you will find that there is no bin folder, etc.
https://github.com/cowboyd/therubyracer

Normally if you want to include a library, you would use require ‘gemname’ but there can be differences. I would read the README from the repository (and it will be in the location the gem installed itself into as well), and as you noticed, it is require ‘v8′.

Reply

Uday January 28, 2014 at 8:24 pm

Hi Satish,

It was a great post! I was wondering, do we have to create the root folder which wraps the /lib folder and other folders inside it?

I am little bit confused about it.

Thanks!

Reply

Satish Talim January 29, 2014 at 4:05 am

Uday, I did physically create the /lib folder.

Reply

gobizen May 13, 2014 at 12:35 pm

Its a great idea and you have written up well learn easily. I’m publishing my first gem soon.

Reply

filozynka June 20, 2014 at 4:47 pm

The more gems, the merrier! This one is also a useful step-by-step tutorial https://netguru.co/blog/posts/creating-a-gem-a-step-by-step-tutorial (with the little help from bundler magic)

Reply

Leave a Comment