Create a Ruby Gem. Real World, play by play. Part 1
Code from screencast and tutorial is available on Github.
Yet another Gem how to tutorial? No way, this one covers the making of a real Gem.
So you want to create a Ruby Gem but you desire a tutorial more advanced than extending the Ruby String
object with a 5 line method? With this tutorial you can follow my steps that led to the conception of a real library, the quickbooks-ruby-base Gem.
- Why do you want to create a Gem?
-
You make a Gem because you want to reuse code. You'll notice a pattern of something you're doing that you'd like to take across projects.
In my case, I do Quickbooks/Rails integration consulting so I was noticing a convention emerging where I was making a base class which would handle some of the dirty work when interacting with the "main" Ruby/QBO library,
quickbooks-ruby
. - How do I name the Gem?
- Starting point: The Gem name should be lowercase with the only special characters being hyphens and underscores.
- I was calling this class, 'QBBase', therefore, I settled on the Gem name 'quickbooks-ruby-base'.
- Since I am extending an existing Gem, what namespace shall I use?
- The quickbooks-ruby Gem simply uses the top-level namespace of 'Quickbooks'.
- So,
Quickbooks::Base
would appear to be good design but let me check that there is no conflicts. - Nice. That namespace is not taken.
- I am now ready to starting coding, so I start by leveraging Bundler's
bundle gem
command to generate a Gem scaffolding. - Modify the lib/ directory structure.
- Next, edit the
quickbooks-ruby-base.gemspec
file to look like this: - Open a new console window and run
git ls-files
command. - After getting the
git ls-files
command in order this is how the the finalquickbooks-ruby-base.gemspec
should look in the figure below. Lastly, run thebundle install
command. - Setup Rspec.
- Create a blank
spec/spec_helper.rb
. - Edit the
Rakefile
, setting a default task that runs the specs. - Create the main spec
spec/quickbooks_ruby_base_spec.rb
with the following basic test. - Run the spec.
- First, I add the
lib/quickbooks-ruby-base.rb
file. - Next, add the
lib/base/base.rb
file. - Let's switch gears and add these new files to git repo so our
git ls-files
is still in order. - Now, re-run the spec.
- Edit the
spec/spec_helper.rb
file to properly reference the core Gem code. - Edit the
spec/quickbooks_ruby_base_spec.rb
file to require thespec_helper.rb
. - Re-run the spec.
- To add color to the spec edit
spec/spec_helper.rb
like so.

$ irb >> require 'quickbooks-ruby' => true >> Quickbooks::Base NameError: uninitialized constant Quickbooks::Base from (irb):2 from /Users/christian/.rvm/rubies/ruby-1.9.3-p484/bin/irb:12:in `'
$ cd ~/github/labs $ bundle gem quickbooks-ruby-base && cd $_

~/github/labs
.

Bundler creates a directory structure off of the hyphens in the name passed into the
bundle gem
command. I don't need the Ruby directory because quickbooks-ruby
only uses the Quickbooks
namespace. The proper directory structure follows the namespacing, which again, is to Quickbooks::Base
.
Gemspec commentary is located at the 8:47 mark in the screencast.

spec.files
section and let's make sure that the git ls-files
is working as expected.

The
git ls-files
remarks are located at the 11:40 mark.

rspec
and quickbooks-ruby
were added also.$ mkdir ~/github/labs/quickbooks-ruby-base/spec $ touch ~/github/labs/quickbooks-ruby-base/spec/spec_helper.rb
require "bundler/gem_tasks" require "rspec/core/rake_task" RSpec::Core::RakeTask.new task :default => :spec task :test => :spec

In the figures you may notice the
be
command. That is an alias for bundle exec
.
Running specs begin at the 19:07 mark in the screencast.

uninitialized Constant Quickbooks
. I know I am going to get an error as I haven't even created the 'Base' class as of yet. Running the specs at this stage act as a guide.
require_relative
within the lib/
directory as this is the directory that is to be included in other projects and libraries.
You will notice the name of file is exactly the same as the Gem. This is so we can do a
require 'quickbooks-ruby-base'
once the Gem is installed.

$ git add spec/ lib/ $ git ls-files # Verify output

uninitialized Constant Quickbooks
.
The problem is in the spec itself. I have no references to the code in the
lib/
directory.

require
instead of require_relative
is fine as specs are for internal development of the Gem.


Good place to stop for Part 1
Please note that the screencasts are already completed for the next 3 parts.
- Pushed on 04/28/2014 by Christian