Creating Your Own Gems

October 26th, 2009 by admin Leave a reply »

Plugins have fallen out of style in the Rails world.  Gems are a better choice because they can be easily versioned and shared across projects.  Using Echoe you can easily package, install and deploy gems.  You can also checkout www.gemcutter.org, a next generation gem repository to host your gems.

Installing Echoe is easy, type ‘sudo gem install echoe‘ at your command prompt.  Echoe provides rake tasks and simplifies the creation of a gem.

You can create a project with the standard directory layout:

/mygem
../lib
../test
..Rakefile
..README.rdoc
..LICENSE
..CHANGELOG

You can optionally include a /bin or /ext if you have executables or extensions.  Just make sure at a minimum you have a Rakefile and lib folder.  You will also want to probably include a readme, license and changelog — it’s just the good citizen thing to do.

Next open your Rakefile and add the following template.  If you want to understand these options or add additional configurations you can reference Echoe’s documentation.

require ‘rubygems’
require ‘rake’
require ‘echoe’
Echoe.new(‘vowels’, ’0.0.1′) do |p|
p.description = ‘Tell whether or not a string starts with a vowel’
p.url = ‘http://www.ozmox.com/’
p.author = ‘Nicholas Cancelliere’
p.email = ‘ncancelliere@gmail.com’
p.ignore_pattern = ['tmp/*', 'script/*']
p.development_dependencies = []  # by default echoe adds itself as a dependency, we override this
end
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext
require 'rubygems'
require 'rake'
require 'echoe'

Echoe.new('vowels', '0.0.1') do |p|
  p.description = 'Tell whether or not a string starts with a vowel'
  p.url = 'http://www.ozmox.com/'
  p.author = 'John Doe'
  p.email = 'jdoe@gmail.com'
  p.ignore_pattern = ['tmp/*', 'script/*']
  p.development_dependencies = []
end

Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }

The configuration is pretty self-explanitory.  Once you have added this template to your Rakefile you can run ‘rake manifest‘ to generate a file manifest automatically.  The manifest is a list of all the files in your gem.

If you plan for people to use your gem you’ll want to write your own tests.  Many folks shy away from poorly tested gems.  Below is a simple module that adds both a class method and instance method.  It isn’t necessarily useful for a real-life situation, but I wanted to demonstrate especially how you create class-methods (since it isn’t as simple as adding self.method).

# lib/vowels.rb
module Vowels
  def self.included(base)
    base.extend ClassMethods
  end
  module ClassMethods
    def is_vowel?(str)
      ['a','e','i','o','u'].include?(str.slice(0,1).downcase)
    end
  end
  def is_vowel?
    "Sorry Vanna White doesn't live here."
  end
end

When this gem is installed, any class that includes Vowels will gain two methods: a class method is_vowel? and an instance method is_vowel?.  We create the class method by adding a module ClassMethods and using a little know-how of the Ruby object lifecycle.

Now that we have our gem written we need to update our manifest, generate a package and install it (build will both update your manifest and package in one action):

rake build
rake install

Now we should be able to utilize our new gem!

# config/environment.rb
config.gem "vowels", :lib => "vowels"

# app/models/contact
class Contact < ActiveRecord::Base
  include Vowels
end

$ contact = Contact.first
=> #<Contact id: 1, name: "Abby Smith">
$ contact.is_vowel?
=> "Sorry Vanna White doesn't live here!"
$ Contact.is_vowel?(contact.name)
=> true

As you can see from the above demonstration, we have successfully created both a class and instance method.  Because our Vowels module is provided by a gem we can use it anywhere as long as we require rubygems and vowels.

That is all there is to creating gems!  Now go create something awesome…

Advertisement

Leave a Reply