Step By Step of Creating a Ruby Gem

By | 2016 年 11 月 9 日

Step By Step of Creating a Ruby Gem

I’m going to create a ruby gem to handle the accents in a string. The gem will replace all the accents to it’s corresponding ascii character. And will achieve this by extending the class String to provide an instance method #accent_to_ascii.

For example:

require 'accent_to_ascii'
"Thìs ìs ā strìng wïth āccēnts".accent_to_ascii
#=> "This is a string with accents"

The initialtive is that those non-ascii codes in the string sometime is not compatible with systems, we need clear them up. But it’s too crude to just remove them with something like gsub(/[^\x20-\x7e]/, ''). And there are a lot of names are with accents in American. So replace those accents with the corresponding ascii characters is a better solution. ( Will make them happy 🙂 )

So in this article will create a gem accent_to_ascii to do this specific task.

Let’s get started:

Steps (story in short)

  1. Create the files for the gem. It’s as simple as just running: bundle gem accent_to_ascii. This will create the gem files from templates into directory ./accent_to_ascii. I prefer the rspec option for testing.
  2. Develop the gem functionality.
    1. Update the gemspec file accent_to_ascii.gemspec with information of the gem.
    2. Write tests in the spec/accent_to_ascii_spec.rb (Test first right?)
    3. Write the core methods in the lib/accent_to_ascii.rb to make tests green
  3. Publish it into, if you already have rubygems account, this is simple as just run rake release

Now let’s diving into the details of the above steps:

1. Gem Creation

Create gem is as simple as just a line of command:

$ bundle gem accent_to_ascii

By running this command, the bundler will create the gem in the directory accent_to_ascii as:

$ tree accent_to_ascii
├── Gemfile
├── LICENSE.txt
├── Rakefile
├── accent_to_ascii.gemspec
├── bin
│   ├── console
│   └── setup
├── lib
│   ├── accent_to_ascii
│   │   └── version.rb
│   └── accent_to_ascii.rb
├── pkg
│   └── accent_to_ascii-0.1.0.gem
└── spec
    ├── accent_to_ascii_spec.rb
    └── spec_helper.rb


The accent_to_ascii.gemspec is the description file of this gem, we can modify it first.


The lib/accent_to_ascii/version.rb defined the version of the gem.

module AccentToAscii
  VERSION = "0.1.0"

The version is defined with a Major.Minor.Patch style:

  • The Major version is for updates will break the backward compatibility;
  • The Minor version is for updates with backward compatibility;
  • The Patch version is for bug fixes with backward compatibility.


This is the test file, we modify this file with the expected behaviors of the gem and make it green by developing the code.


This is the main code file.

2.1 Update the gemspec file

Just provide the informations in the TODO section, and I make it as:

# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'accent_to_ascii/version' do |spec|          = "accent_to_ascii"
  spec.version       = AccentToAscii::VERSION
  spec.authors       = ["uniEagle"]         = [""]

  spec.summary       = %q{Rubygem to replace accents in string into the corresponding ascii chars}
  spec.description   = %q{Replace the non ascii accents in a string}
  spec.homepage      = ""
  spec.license       = "MIT"

  spec.files         = `git ls-files -z`.split("\x0").reject do |f|
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.13"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec", "~> 3.0"

2.2 Write the tests

The in the test file /spec/accent_to_ascii_spec.rb, added several tests to reflect the expected behavior of this gem:

require "spec_helper"

describe AccentToAscii do
  it "has a version number" do
    expect(AccentToAscii::VERSION).not_to be nil

  it { expect("São Paulo".accent_to_ascii).to eq "Sao Paulo" }
  it { expect("Tẽst".accent_to_ascii).to eq "Test" }

  it "does not change original string" do
    str = "São Paulo"
    expect(str.accent_to_ascii).to eq "Sao Paulo"
    expect(str).to eq "São Paulo"

  context "hungarian accents" do
    specify { expect("fejlődő".accent_to_ascii).to eq "fejlodo" }
    specify { expect("FEJLŐDŐ".accent_to_ascii).to eq "FEJLODO" }
    specify { expect("fű".accent_to_ascii).to eq "fu" }
    specify { expect("FŰ".accent_to_ascii).to eq "FU" }

  context "accent_to_ascii!" do
    let(:str) { "São Paulo" }

    it "changes original string" do
      expect(str.accent_to_ascii!).to eq "Sao Paulo"
      expect(str).to eq "Sao Paulo"

And of course, if you run rake, almost all the tests will fail:

$ rake
... some test errors ...
Finished in 0.0024 seconds
9 examples, 8 failures

2.3 Write some real code and make the tests green

The file /lib/accent_to_ascii.rb is the target file. I just made it as the following:

require "accent_to_ascii/version"

module AccentToAscii
    'E' => [200,201,202,203],
    'e' => [232,233,234,235,7869],
    'A' => [192,193,194,195,196,197],
    'a' => [224,225,226,227,228,229,230],
    'C' => [199],
    'c' => [231],
    'O' => [210,211,212,213,214,216,336],
    'o' => [242,243,244,245,246,248,337],
    'I' => [204,205,206,207],
    'i' => [236,237,238,239],
    'U' => [217,218,219,220,368],
    'u' => [249,250,251,252,369],
    'N' => [209],
    'n' => [241],
    'Y' => [221],
    'y' => [253,255],
    'AE' => [306],
    'ae' => [346],
    'OE' => [188],
    'oe' => [189]

  def self.accent_to_ascii(string)
    string.tap do |s|
      ACCENTS_MAPPING.each { |letter, accents| replace(s, letter, accents) }


  def self.replace(string, letter, accents)
    packed = accents.pack('U*')
    regex ="[#{packed}]", nil)
    string.gsub!(regex, letter)


class String
  def accent_to_ascii(string =

  def accent_to_ascii!

Special thanks to the Github project accentless, reused the ACCENTS_MAPPING in that project.

Then the tests are green now:

$ rake
  has a version number
  should eq "Sao Paulo"
  should eq "Test"
  does not change original string
  hungarian accents
    should eq "fejlodo"
    should eq "FEJLODO"
    should eq "fu"
    should eq "FU"
    changes original string

Finished in 0.00283 seconds
9 examples, 0 failures

3. Package and Publish

If you already have rubygems account registered and configured well, it’s just as simple as a single command:

$ rake release

Or, just sign up in the, then run the following command:

$ gem push pkg/accent_to_ascii-0.1.0.gem

The first time run this command will ask you input your account information for

And for the following up changes, just update the version and run rake release.


[Engineering Lunch Series] Step-by-Step Guide to Building Your First Ruby Gem

Official Guide of Publish Gems onto


电子邮件地址不会被公开。 必填项已用*标注