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
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
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
Then add a file: lib/states/hawaii.rb
puts "in hawaii"
Then I added a test file. Then in spec/spec_helper.rb, add
I added the file spec/states/hawaii_spec.rb
describe Hawaii do
it "should do something" do
hawaii = Hawaii.new
There is another way to recognize the module levels in the RSpec file:
describe States::Hawaii do
it "should do something" do
hawaii = States::Hawaii.new
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
Then to add RSpec, I ran
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.
│ ├── states
│ │ ├── hawaii.rb
│ │ ├── illini
│ │ │ ├── champaign
│ │ │ │ └── urbana.rb
│ │ │ └── champaign_county.rb
│ │ ├── illinois.rb
│ │ └── version.rb
│ └── states.rb
│ ├── spec_helper.rb
│ └── states
│ ├── hawaii_spec.rb
│ ├── illini
│ │ ├── champaign
│ │ │ └── urbana_spec.rb
│ │ └── champaign_county_spec.rb
│ └── illinois_spec.rb
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.