How to create your own Ruby gem

April 6, 2013 · Posted in Development 

This post is the guide to creating your own gem for Rails.

What is a Ruby gem?

A gem is a ruby library in a self-contained format.

The gems are handled by RubyGems, which is a package manager for Ruby that provides a standard format for distributing the gems. As of ruby 1.9 RubyGems comes with Ruby.

Someone can write their own library and then package it as a gem file so that it can be used in any Rails application. Another programmer can install and access its functionality as any other known gems (gem install mygem).

It means that a gem is a generic library, which can be easily installed, which are version-managed, have dependencies.

Gems vs. Plugins vs. Engines vs. Realties

Gems and Plugins:

- Gems and Plugins are identical in terms of the code and function you actually write, therefore creating a gem is often referred to as “packaging” something as a gem.

- Gems are version-managed, have dependencies. Gems can be easily installed.

- Gems are platform independent, which means you can use them in any Ruby environment (such as Rails or Sinatra)

- Plugins are Rails-only and you can’t manage or version them.

 

Rails has a plugin system where you type “script/plugin install <plugin-name>” but packaging it up as a gem is better because its cleaner and allows for better dependency resolution.

 

Realtie

// see http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html

Railtie is the core of the Rails framework and provides several hooks to extend Rails and/or modify the initialization process.
Every major component of Rails (Action Mailer, Action Controller, Action View and Active Record) is a Railtie. Each of them is responsible for their own initialization. This makes Rails itself absent of any component hooks, allowing other components to be used in place of any of the Rails defaults.

 

Engine

An Engine is a sub-application of a Rails application.

Engines are miniature applications that live inside your application and they have structure that you would normally find in a typical Rails application.

If you have used Devise gem, which itself is an engine, you know the benefits of being able to add functionality to your application with just a few lines of code.

These are not full applications, but pages/views/controllers/models that can be added to any rails application.

A Rails::Engine is nothing more than a Railtie with some initializers already set.

 

Engines are already available prior to Rails 3 but it is not a core feature of the framework. As such, engine developers resorted to monkey-patching which, oftentimes, lead to engines breaking when Rails gets updated.

Since Rails 3 an engine can be packaged and distributed as a gem.

In Rails 3.1, engines are now supported by the framework and there is now a clearly defined place where to hook your engines into Rails.

 

Read this blog about creating your own Rails 3 Engine:

http://gregmoreno.wordpress.com/2012/05/29/create-your-own-rails-3-engine/

Create your first gem

Let’s name our first gem as ‘myfirst’.

- Create a new directory which will contain our new gem

- Create gemspec file
The first thing to do when creating a new gem is to create a file called gemspec that contains information about the gem. The gemspec file must be named ‘mygemname.gemspec’.

File ‘myfirst.gemspec’:

Gem::Specification.new do |s|
s.name = "myfirst"
s.version = '0.0.1'
s.date = '2013-04-06'
s.authors = ["Max Ivak "]
s.email = ["maxivak@gmail.com"]
s.summary = "My very first"
s.description = "Simple Hello World"
s.homepage = "http://github.com/maxivak/myfirst"
#s.files = ["lib/mygem3.rb"]
# or
s.files = Dir["{lib}/**/*.rb", "bin/*", "LICENSE", "*.md"]
end

Find all options here – http://guides.rubygems.org/specification-reference/.
Notice this line:
s.files       = Dir["{lib}/**/*.rb", "bin/*", "LICENSE", "*.md"]

It will include all rb files in lib directory.

 

- code for library

Let’s create ruby code for our library in file lib/myfirst.rb.

We create a simple class with a simple class method.

File ‘lib/myfirst.rb’:

class Myfirst
def self.hi
return "Hello world"
end
end

 

- build gem

gem build myfirst.gemspec

You should see the following result:

WARNING: licenses is empty
Successfully built RubyGem
Name: myfirst
Version: 0.0.1
File: myfirst-0.0.1.gem

It will package your gem project into a gem file that can be used to install the gem. This file has name like gemname-version.gem where with the gemname and version are specified in the gemspec file.
In our case it will create a file myfirst-0.0.1.gem.
- check if your gem is available:

gem list | grep myfirst

Use gem in an application

Use gem locally:
Install it locally

gem install ./myfirst-0.0.1.gem

Now you can use your gem in your local Rails application.
Just include it in Gemfile:
gem 'myfirst'

Then you can access gem’s functionality:

s = Myfirst.hi

Also you can test it in IRB console:
irb
irb(main):001:0> require 'myfirst'
=> true
irb(main):002:0> Myfirst.hi
=> "Hello world"
irb(main):003:0> puts Myfirst.hi
Hello world
=> nil
irb(main):004:0> quit

Publish to RubyGems

You can share your gem to Ruby community by publishing it to RubyGems.org.
- Setup your RubyGems account.
Go to rubygems.org and create a new account.

- Deploy gem to RubyGems:

gem push myfirst-0.0.1.gem

It will ask to enter your credentials (email and password).
After that the gem is published:

Pushing gem to https://rubygems.org...
Successfully registered gem: myfirst (0.0.1)

Note: If you don’t want to enter credentials all time to publish your gem, read  the tutorial – http://guides.rubygems.org/make-your-own-gem/

You can see your gem on RubyGems.org site in your account. The link will be like this:

https://rubygems.org/gems/myfirst

- Check that your gem is available:

gem list -r myfirst
*** REMOTE GEMS ***
myfirst (0.0.1)

Other developers can now install your gem:

gem install myfirst

Test gem

Gems support adding test files into the package itself so tests can be run when a gem is downloaded.

Below we will create a simple test using Ruby’s built-in test framework Test::Unit.

Create a new file ‘Rakefile’ and ‘test’ directory.

- Rakefile:

require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << 'test'
end
desc "Run tests"
task :default => :test

- Basic test for our class:

test/test_myfirst.rb:

require 'test/unit'
require 'myfirst'
class MyfirstTest < Test::Unit::TestCase
def test_hi
assert_equal "Hello world",
Myfirst.hi
end
end

 

- run the tests:

rake test
# Running tests:
.
Finished tests in 0.001000s, 1000.0000 tests/s, 1000.0000 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips

You should see that all the tests passed.

Build a new version of gem

Let’s modify our gem by adding a new method.

lib/myfirst.rb

class Myfirst
def self.hi
return "Hello world"
end
def self.sum(x,y)
return x+y
end
end

- gemspec
Modify the specification of the gem by changing the version to ’0.0.2′:

Gem::Specification.new do |s|
s.name        = "myfirst"
s.version     = '0.0.2'
s.date        = '2013-04-07'
s.authors     = ["Max Ivak "]
s.email       = ["maxivak@gmail.com"]
s.summary     = "My very first"
s.description = "Simple Hello World"
s.homepage    = "http://github.com/maxivak/myfirst"
s.files       = Dir["{lib}/**/*.rb", "bin/*", "LICENSE", "*.md"]
end

- Build

gem build myfirst.gemspec

After this you should see a new file myfirst-0.0.2.gem.

- publish
Now publish a new version to RubyGems

gem push myfirst-0.0.2.gem

- Check
Finally, check that a new version is available at RubyGems – https://rubygems.org/gems/myfirst.
You should see two versions of your gem: ’0.0.1′ and ’0.0.2′.

Gems to build your own gem

You use one of the gems that help you build a gem, including

gem-thishoe, newgem, bones, gemhub, and echoe.

References

Read more details about creating a gem at official guide – http://guides.rubygems.org/make-your-own-gem/

* The Basics of Creating Rails Plugins – http://guides.rubyonrails.org/plugins.html

 

Realties

* Creating your Railtie – http://edgeapi.rubyonrails.org/classes/Rails/Railtie.html

 

Engines:

* Getting Started with Engines – http://edgeguides.rubyonrails.org/engines.html

* Create your own Rails 3 Engine – http://gregmoreno.wordpress.com/2012/05/29/create-your-own-rails-3-engine/

 

Create your own gem using jeweler

* Jeweler gem – https://github.com/technicalpickles/jeweler
* http://blog.galk.me/post/7443618295/getting-started-with-gems-how-to-create-a-gem-for

* http://kashirevanna.blogspot.com/2011/12/ruby-gem-jeweler.html

 

 

Comments