RubyGems

Managing your Ruby Gems with RubyGems and the gem command.

RubyGems is a package manager

RubyGems is a package manager for Ruby gems, and has been a part of Ruby itself since version 1.9.2. Ruby gems are hosted on gem servers, the most important of which is rubygems.org. The command line interface to the rubygems.org API is via the gem command. With gem you can search gem servers, download gems, install, update, and delete gems. There are other commands as well. You can read the docs for gem commands, or type

% gem help commands

Installing a gem puts the contents of the gem package in a directory with other gems. These collections of installed gems are sometimes called gemsets.

2.1.2 hubble ~/test % gem install --install-dir gemdir yamlconfig
Fetching: yamlconfig-0.2.2.gem (100%)
Successfully installed yamlconfig-0.2.2
1 gem installed
2.1.2 hubble ~/test % ls
gemdir/
2.1.2 hubble ~/test % ls gemdir
build_info/     cache/          doc/            extensions/     gems/           specifications/
2.1.2 hubble ~/test % tree gemdir
gemdir
├── build_info
├── cache
│   └── yamlconfig-0.2.2.gem
├── doc
├── extensions
├── gems
│   └── yamlconfig-0.2.2
│       ├── Gemfile
│       ├── Rakefile
│       ├── lib
│       │   ├── LICENSE
│       │   ├── yamlconfig
│       │   │   └── version.rb
│       │   └── yamlconfig.rb
│       ├── spec
│       │   ├── data
│       │   │   ├── accessor_config
│       │   │   ├── accessor_config_tmp
│       │   │   ├── complex_values
│       │   │   ├── config
│       │   │   ├── empty_file
│       │   │   ├── flatulentmonkey
│       │   │   └── freakboy
│       │   ├── spec_helper.rb
│       │   └── yamlconfig_spec.rb
│       └── tags
└── specifications
    └── yamlconfig-0.2.2.gemspec

11 directories, 17 files
2.1.2 hubble ~/test %

So how does a Ruby program locate and use the code in a gem? The Ruby Kernel consults a load path when it encounters a *require * statement, looking for a gem that matches the required name. When a Ruby script *requires 'rubygems'*, rubygems replaces Kernel#reqire with its own #require. Now *require* will invoke rubygems#require to activate the specificed gem. If the required gem is already on the load path ($LOAD_PATH), rubygems#require sends control to Kernel#require. If the required gem is not found on the current load path, Rubygems finds the specified gem's code and modifies the Ruby load path ($LOAD_PATH) to include the gem's directory. In this way the load path is constructed to point to the code for installed gems.

2.1.2 hubble ~/test % irb
irb(main):001:0> puts $LOAD_PATH
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/site_ruby/2.1.0/x86_64-darwin13.0
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/site_ruby
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby/2.1.0/x86_64-darwin13.0
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/vendor_ruby
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/2.1.0
/Users/jfnixon/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0
=> nil

On an ending note, Ryan Tomayako of Sinatra fame makes an excellent point that using require ‘rubygems’ in library code and apps is probably the wrong thing to do. You can read his explanation at this Gist.