I’ve created my gem, but can’t require it
Creating gems is easy, all you need is a gemspec:
Gem::Specification.new do |spec|
spec.name = 'chubby-bat'
spec.version = '0.0.1337'
spec.files = [
'./lib/chubby_rain.rb',
'./lib/crack_murphy.rb',
]
spec.summary = 'An example gem'
spec.author = 'Ben Biddington'
end
And then to build it:
$ gem build chubby-bat.gemspec
And then to install it:
$ gem install chubby-bat-0.0.1337.gem
No such file to load — xxx
Trouble is, when requiring the new gem, you may encounter an error like:
irb(main):001:0> require 'chubby-bat'
LoadError: no such file to load -- chubby-bat
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`gem_original_require'
from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from (irb):1
irb(main):002:0>
I found this pretty confusing, until I realised the interpreter is looking for a file called chubby-bat.
In short, a gem needs to contain a file with the same name as the gem itself in its lib folder:
And gemspec becomes:
Gem::Specification.new do |spec|
spec.name = 'chubby-bat'
spec.version = '0.0.1337'
spec.files = [
'./lib/chubby-bat.rb',
'./lib/chubby_rain.rb',
'./lib/crack_murphy.rb',
]
spec.summary = 'An example gem'
spec.author = 'Ben Biddington'
end
Rubygems require
The comment in rubygems custom_require explains:
# See: path/to/Ruby/lib/ruby/site_ruby/1.8/rubygems, custom_require ## # When RubyGems is required, Kernel#require is replaced with our own which # is capable of loading gems on demand. # # When you call require 'x', this is what happens: # * If the file can be loaded from the existing Ruby loadpath, it # is. # * Otherwise, installed gems are searched for a file that matches. # If it's found in gem 'y', that gem is activated (added to the # loadpath). # # The normal require functionality of returning false if # that file has already been loaded is preserved.
Ruby loadpath, gem install and Kernel#require
Installing a gem simply copies files to somewhere in $LOAD_PATH, and invoking require triggers a file search within these locations.
Kernel require does the following:
- Ruby tries to load the library named string, returning true if successful.
- If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $:.
- If the file has the extension “.rb’’, it is loaded as a source file; if the extension is “.so’’, “.o’’, or “.dll’’,or whatever the default shared library extension is on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding “.rb’’, “.so’’, and so on to the name.
- The name of the loaded feature is added to the array in $”.
- A feature will not be loaded if it‘s name already appears in $”.
This means if you print out the contents of $”, you’ll see chubby-bat.rb in there.


Thanks! Stumbled upon this for a while….. Thought I had messed up my rvm env but this explains my confusion clearly!
Fredrik Rubensson (@froderik)
6 September, 2011 at 08:25