I decided to make a gem for a bit of practice. I did some googling, and I found a good RailsCast on it.
He uses bundler, which takes care of a lot of the heavy lifting. All I did was run
bundle gem states
This will create a directory with the same name as whatever you called the gem. Then to add RSpec, cd to the directory that was created. Then run
rspec --init
I wanted to make a gem with a few layers in the directory tree. Java package names tend to have multiple levels, while most Ruby gems seem to only go one level deep. Perhaps I will never write a gem that has too many levels, but I wanted to make one with a few levels anyway.
I decided to start with a state in the first level. I added
require "states/hawaii"
to lib/states.rb
Then add a file: lib/states/hawaii.rb
module States class Hawaii def initialize puts "in hawaii" end end end
Then I added a test file. Then in spec/spec_helper.rb, add
require 'states'
I added the file spec/states/hawaii_spec.rb
require "spec_helper" module States describe Hawaii do it "should do something" do hawaii = Hawaii.new end end end
There is another way to recognize the module levels in the RSpec file:
require "spec_helper" describe States::Hawaii do it "should do something" do hawaii = States::Hawaii.new end end
I put
require 'spec_helper'
in each spec file.
I also added a class lib/states/illinois.rb, and a test file in spec/states/illinois_spec.rb.
I then tried to add a few classes for Champaign County and Urbana. I tried to put them in a directory lib/states/illinois and in spec/states/illinois.
I got this error:
lib/states/illinois/champaign_county.rb:2:in `<module:States>': Illinois is not a module (TypeError)
But I changed the directory name to illini, and I updated the files accordingly, and it worked. I changed it all back to “Illinois”, and it stopped working again. So now the module is back to “Illini”. I do not know if Ruby or RSpec will not allow a directory and a class to have the same name, or if I just needed to put illinois.rb in a higher directory. There is a states.rb and a states directory. Perhaps the gem name is an exception to the uniqueness rule. But in the future I will stick with using different names.
So, to summarize, I ran
bundle gem states
Then to add RSpec, I ran
rspec --init
For every class that I made, I put a file in lib, a corresponding file in spec, and I put a require statement in the states.rb file.
And the class file names must not be the same as the directory names.
ericm:/states$ tree . ├── Gemfile ├── lib │ ├── states │ │ ├── hawaii.rb │ │ ├── illini │ │ │ ├── champaign │ │ │ │ └── urbana.rb │ │ │ └── champaign_county.rb │ │ ├── illinois.rb │ │ └── version.rb │ └── states.rb ├── LICENSE ├── notes.txt ├── Rakefile ├── README.md ├── spec │ ├── spec_helper.rb │ └── states │ ├── hawaii_spec.rb │ ├── illini │ │ ├── champaign │ │ │ └── urbana_spec.rb │ │ └── champaign_county_spec.rb │ └── illinois_spec.rb └── states.gemspec 8 directories, 17 files
—
I am sure that for a lot of Ruby people, this post will be review. I tried making a gem using some of the code from the RSpec book as a basis, and I could not get it to work. I did the guy thing by trying something without reading the directions. I am thinking of proposing a talk for Lone Star Ruby Conf, and I need to be able to get a gem to work.