Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me

Ruby: GEM_HOME, GEM_PATH do what?

Ruby is a modular language.

I use RubyGems to build Ruby applications from other developers' reusable Ruby code.

I find RubyGems at this site:

Perhaps the most well known RubyGem is 'Ruby on Rails' AKA Rails:

When I study the above page I see the modular nature of Ruby because I notice that Rails depends on many other gems.

On my Ubuntu laptop I recently installed Ruby with a simple shell command:
apt-get install ruby ruby-dev
Next, I created a folder for a demo app:
mkdir /tmp/demo1
Then, I attached a RubyGem folder to the app:
mkdir /tmp/demo1/gems
Next, I copied a RubyGem into the folder with the help of the GEM_HOME shell variable:
export GEM_HOME=/tmp/demo1/gems
gem install haml
ls -la /tmp/demo1/gems
I see GEM_HOME as part of a 'setter mechanism'. Above, It sets, or declares, that /tmp/demo1/gems will be the home of any RubyGems which I may install in the future.

Then, I added more folders to /tmp/demo1/
mkdir /tmp/demo1/bin /tmp/demo1/haml /tmp/demo1/html
Next, I created a simple haml file, /tmp/demo1/haml/index.haml, which looks like this:

    %title hello world
      I can use haml to create html.
    alert('JavaScript can be in haml files');
Then, I created a shell script which uses GEM_PATH as part of a 'getter mechanism':

# runme.bash

cd /tmp/demo1/

export GEM_PATH=/tmp/demo1/gems

$GEM_PATH/bin/haml /tmp/demo1/haml/index.haml /tmp/demo1/html/index.html 

cat /tmp/demo1/html/index.html 

In the above script, I use GEM_PATH to declare that my app will get RubyGems from this folder:
I avoid getting RubyGems from the default location which might be under /var/lib/ somewhere.

To find the default folders where Ruby searches for RubyGems, I run three shell commands:
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ unset GEM_HOME GEM_PATH
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ which gem
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ gem env
RubyGems Environment:
  - RUBY VERSION: 1.9.3 (2013-11-22 patchlevel 484) [x86_64-linux]
  - INSTALLATION DIRECTORY: /var/lib/gems/1.9.1
  - RUBY EXECUTABLE: /usr/bin/ruby1.9.1
  - EXECUTABLE DIRECTORY: /usr/local/bin
    - ruby
    - x86_64-linux
     - /var/lib/gems/1.9.1
     - /home/dan/.gem/ruby/1.9.1
     - :update_sources => true
     - :verbose => true
     - :benchmark => false
     - :backtrace => false
     - :bulk_threshold => 1000
     - "gem" => "--no-ri --no-rdoc"
     - "install" => "--env-shebang"
     - "update" => "--env-shebang"
     - :sources => ["", ""]
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ 
When I run the script, /tmp/demo1/bin/runme.bash, I see the following output:
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ /tmp/demo1/bin/runme.bash 
    <title>hello world</title>
    <div class='simple_div' id='div1'>
      I can use haml to create html.
    alert('JavaScript can be in haml files');
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ 

I prefer to use GEM_HOME and GEM_PATH for simple ruby apps.

The above app, /tmp/demo1, is simple; it uses one gem named haml.

If I have a ruby app which is more complex and depends on many RubyGems, I enhance my use of GEM_HOME.


I use 'Bundler' (which happens to be a RubyGem).

Bundler asks me to use a file named 'Gemfile' to declare which RubyGems my app depends upon.

I keep in mind that Bundler does not replace GEM_HOME; Actually Bundler depends on GEM_HOME.

If I want /tmp/demo1 to use Bundler I create /tmp/demo1/Gemfile.

That file might look like this:
# /tmp/demo1/Gemfile
source ''
gem 'haml','4.0.7'
I use the above Gemfile to declare that my app depends on haml(specifically, version 4.0.7 of haml).

To use bundler I need to install it with this shell command:
gem install bundler
Then I need to use its shell command:

dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ export GEM_HOME=/tmp/demo1/gems
dan@usb99:/tmp/demo1 $ export GEM_PATH=/tmp/demo1/gems
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ gem list

*** LOCAL GEMS ***

bundler (1.10.6)
haml (4.0.7)
tilt (2.0.1)
dan@usb99:/tmp/demo1 $ bundle install
The program 'bundle' is currently not installed. You can install it by typing:
sudo apt-get install bundler
dan@usb99:/tmp/demo1 $ 
dan@usb99:/tmp/demo1 $ 

I need to remember that the bundle shell command comes from a RubyGem. So I will find the bundle shell command under $GEM_HOME.
dan@usb99:/tmp/demo1 $ dan@usb99:/tmp/demo1 $ $GEM_HOME/bin/bundle install Fetching gem metadata from Fetching version metadata from Resolving dependencies... Using tilt 2.0.1 Using haml 4.0.7 Using bundler 1.10.6 Bundle complete! 1 Gemfile dependency, 3 gems now installed. Use `bundle show [gemname]` to see where a bundled gem is installed. dan@usb99:/tmp/demo1 $ dan@usb99:/tmp/demo1 $ dan@usb99:/tmp/demo1 $
The beauty of Bundler is that it declares which RubyGems that an app depends upon.

If I have a Rails app which depends on many different RubyGems, and I also require that some of the RubyGems be specific versions, then the power of Bundler becomes clear. Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me