In the previous post, we saw how to set up the gemspec and also installed the empty gem into our rubygems directory. Now it’s time we started adding some code to our gem.
Create a directory called lib/ and save a file sudoku.rb with the following code:
module Sudoku # hopefully someday this module will solve Sudoku. end
It’s not much code, and it doesn’t do much, but we have to start somewhere. Now build and install the gem as we did in the previous part of this tutorial:
$ gem build sudoku.gemspec $ gem install sudoku-0.0.0.gem
If you check the installation path for your gem in the rubygems folder, you will still find it empty. This is because rubygems doesn’t know what files to package into our gem. To fix that, let’s tell the gemspec what files need to be added.
Gem::Specification.new do |s| # rest of the stuff s.files = Dir.glob(“lib/**/*.rb”) end
Build and install the gem again, and this time you’ll find lib/sudoku.rb in the gem installation directory.
Gem authors often use a version.rb file to store the version information. It’s always prudent to use a separate directory within the lib directory to put your code. This is because
require 'yourgem' causes rubygems to add your gem’s lib/ to the load path. Now every require statement will also look at the files in your lib/ and it’s possible that the names might clash with some other gem.
The convention is to have a directory within lib/ with the same name as the gem. This way only sudoku.rb will be loaded from the load path and we can safely
require 'sudoku/version' within sudoku.rb to access version.rb.
We’ll add version.rb in lib/sudoku and we should now have a gem directory structure that looks like this:
sudoku ├── lib │ ├── sudoku │ │ └── version.rb │ └── sudoku.rb └── sudoku.gemspec
Let’s now add the version information in version.rb:
module Sudoku. VERSION = '0.0.0' end
And now use this in the gemspec by using
Sudoku::VERSION instead of using the string “0.0.0” directly.
$LOAD_PATH.push File.expand_path("../lib", __FILE__) require 'sudoku/version' Gem::Specification.new do |s| s.name = "sudoku" s.version = Sudoku::VERSION # .. other stuff end
The first line adds the lib/ directory of your gem to ruby’s load path, so you can include the files within that directory relative to your load path. For instance
require 'sudoku' would load lib/sudoku.rb. Here we need the version.rb file for accessing Sudoku::VERSION constant, so we use
require 'sudoku/version' to add lib/sudoku/version.rb.
As you may have noticed, we’re still not any closer to having a working sudoku solver, but we’ve learned a lot about how to create a bare gem and organize the files within it.
Don’t worry, we’ll eventually get to writing the actual sudoku solver. In the meanwhile, we’ll also look at publishing our awesome gem to rubygems.org and setting up tests using Test::Unit and Rspec in the next 2-3 posts.