The Ruby VM market is thriving, and we increasingly find ourselves spending the morning in JRuby and the afternoon in Ruby Enterprise Edition. Or Thursday using Leopard Ruby and Friday using Ruby 1.9. Or … well, you get the idea. So we needed a lightweight tool that eliminates the cost (in both time and frustration) of switching between Ruby versions. We wanted something drop-dead simple. Meet the Ruby Switcher.
Hello, Ruby Switcher
The Ruby Switcher debuted earlier this year as a means for toggling between a handful of pre-installed Ruby versions. And once you bit the bullet and manually installed those VMs, and assuming you installed them in the “right” location, the Ruby Switcher offered crazy-fast switching between those few Ruby versions. But we’re passionate about continuous improvement and maintaining a sharp set of tools, so we recognized that switching Ruby versions was Step 2; Step 1 (i.e., installing those Ruby versions in the first place) needed a healthy dose of automation as well. Today’s Ruby Switcher makes both steps insanely simple, and it adds support for more (and newer) Ruby versions as well.
Pick a Ruby, Any Ruby
Enough talk! Let’s download the Ruby Switcher and get this party started.
cd
curl -O -L http://github.com/relevance/etc/raw/26ae85c2f6c7d2640a3c75d619ad7ab8fc1cc570/bash/ruby_switcher.sh
echo "source ~/ruby_switcher.sh" >> .bash_profile
source .bash_profile
That’s it. Let’s quickly verify that you have your platform’s core developer tools installed, and then you’ll be ready to put the Ruby Switcher to work.
Prerequisites - Compilers, Libraries, and Whatnot
If you’re on OS X, you’ll need to download and install Xcode. (If you just want to switch between Leopard Ruby and JRuby, you can skip this step. If you want to use any other versions of Ruby, you’ll need Xcode.)
If you’re using Ubuntu, use apt-get to grab a few essential packages:
sudo apt-get update
sudo apt-get install build-essential zlib1g-dev libreadline5-dev libssl-dev
For other *nix variants … well, clearly you enjoy figuring this stuff out.
Ruby 1.9
Yehuda Katz recently asked the Ruby community what we need in order adopt Ruby 1.9. Having an easy way to experiment with Ruby 1.9 is surely a good place to start. What could be easier than a single command?
install_ruby_191
The installation will take a few minutes. In the meantime, why not check out Bruce Williams’ slides on Ruby 1.9 from last year’s Lone Star Ruby Conference — Ruby 1.9: What’s New and Why it Matters?
...
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
checking for gcc... gcc
...
installing rdoc
Using ruby 1.9.1p129 (2009-05-12 revision 23412) [i686-linux]
Successfully installed rake-0.8.7
1 gem installed
By the time you’re done reading through the Ruby 1.9 highlights,
you’ll be ready to take it for a spin.
Type ruby -v to verify that you’re rockin’ with 1.9.1.
ruby 1.9.1p129 (2009-05-12 revision 23412) [i686-linux]
JRuby
Installing and using JRuby is just as easy.
First, be sure that you have the JDK installed.
If you’re using OS X, you’re all set.
If you’re on Ubuntu, you can install it with apt-get.
(For other Linux distros, you can ask your native package manager for the JDK bits.)
sudo apt-get update
sudo apt-get install sun-java6-jre sun-java6-jdk
With the JDK in place, installing JRuby is a cinch.
install_jruby
Verify the results with ruby -v.
jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 2fd6c3d) (Java HotSpot(TM) Client VM 1.6.0_10) [i386-java]
Wait a minute: shouldn’t we have typed jruby -v instead of ruby -v?
Sure you can do that if you really want to.
But we’re not big on having to remember to type jirb instead of irb, or jgem instead of just gem, etc.
Once we tell the shell to use JRuby, we want the normal Ruby commands to just work.
The Ruby Switcher ensures that they do.
Ruby.*
Looking for yet another Ruby version? See what else the Ruby Switcher has to offer:
install_ree_186install_ruby_186install_ruby_187install_jruby_120
And if you find yourself wanting some other Ruby variant, be sure to check out the Ruby Switcher’s internals; you can likely adapt one of the existing installation functions to meet your exact need.
Willy-nilly Switching
Once you have the desired Ruby versions installed,
switching between them couldn’t be easier.
Each of the install commands comes with a corresponding use command to instruct your shell to switch to the specified Ruby version:
| Install It | Use It |
|---|---|
install_ruby_191 |
use_ruby_191 |
install_ruby_186 |
use_ruby_186 |
install_ruby_187 |
use_ruby_187 |
install_jruby |
use_jruby |
install_jruby_120 |
use_jruby_120 |
install_ree_186 |
use_ree_186 |
| N/A [1] | use_leopard_ruby |
And these commands are shell-specific! So while one terminal window is using Ruby 1.8.7 to run your front-end Rails app, you can have another terminal using JRuby to run your back-end messaging code.
Ruby 1.9, the Community, and You
Want to see whether your app runs on Ruby 1.9?
Flip your shell to use_ruby_191 and try it out.
It’s that kind of experimentation that will allow the Ruby community to make the migration to Ruby 1.9.
See a problem with a certain gem on Ruby 1.9? Let the gem author know about it and chime in at isitruby19.com. Better yet, write a test that proves the bug and pass that test along to the author. Better still, fix the issue and submit a patch. Any one of these steps moves us forward, and all the while you’ve still got your default Ruby installation standing safely by for your day job.
When switching between Ruby versions is this seamless, there’s no reason not to experiment.
Notes
[1] Ruby is installed by default on OS X Leopard, so there’s no need for an install_leopard_ruby command.
Image courtesy of bdu (flickr.com/bdu). [Creative Commons License]

Comments
If the ruby versions are shell-specific, how do you handle cases such as: 1. You want to test a development site using Passenger with a specific Ruby 2. Can you specify a version of Ruby to use when running tests in Textmate using command-r?
Thanks.
Awesome!!!!
Even though you guys are the Ruby pros leveraging use_ruby_XXX, in some ways, this is actually a tool that provides the most value for Ruby novices like myself. When learning Ruby, it seems that each book or tutorial has an expectation on a given version. This makes aligning with book samples trivial. Thanks!
Very Cool! You might want to change:
echo “source ~/ruby_switcher.sh” >> .bash_profile
to
echo ”\nsource ~/ruby_switcher.sh” >> .bash_profile
As it pushed the source command on the same line as the last line in my bash_profile
Thanks! I’d played with Ruby 1.9 before, but installing was a bit of a pain. This will make it easier to test patches to Rails, too.
Yeah! great post, everything works as i thought
Just a quick thank you, this works really well. I had something similar hacked together, but not nearly as comprehensive. Also this makes setting up new machines a breeze.
yay, 808!
@Erik Runyon,
It would be nice to be able to quickly change the Ruby version in use by Passenger. I haven’t tried that yet, but this [1] looks like the right starting point.
TextMate uses a shell variable called “TM_RUBY” (available in the “advanced” tab of the TextMate Preferences) to determine which Ruby to use. You could probably set up some TextMate commands to make it easy to quickly change that value to Ruby 1.9.1, JRuby, etc. (We tend to run our tests from the command line with beholder [2], so this isn’t an itch we’ve felt the need to scratch just yet.)
If you dig into either of these items, please let us know what you find.
[1] http://www.modrails.com/documentation/Users%20guide.html#specifying_ruby_installation
[2] http://github.com/spicycode/beholder
It works! Very good and secure way for the community to move to ruby 1.9.1. Thanks!
Oh this all colours of awesomeness.
This is just the tool I have needed. Two notes:
The default ruby is always set to leopard ruby in the script, simply replace the last line with the use_ command you prefer.
I had settings in .bash_login that were ignored after adding the .bash_profile, I simply moved the necessary line to .bash_login.
Thank you! You often write very interesting articles. You improved my mood.
Good stuff, this has made my day.
One error in the use_ruby_191 function:
“export GEM_HOME=/.gem/ruby/1.9” should read “export GEM_HOME=/.gem/ruby/1.9.1”
Looking at your script, it looks like you’re using the same gem directory for all the various ruby 1.8 installs. I was under the impression this would cause problems fr gems with native extensions due to various issues, as mentioned here about REE http://www.rubyenterpriseedition.com/documentation.html#_how_ree_installs_itself_into_the_system
Have you found that in practice this isn’t an issue?
I’ve been putting off using REE on my dev machine for so long… But you know, I’m lazy and busy.
Now with 2 commands that worked flawlessly I got it up and running :-) Thanks guys!
You can make sure to grab the latest version of the script by using this URL instead
http://github.com/relevance/etc/raw/master/bash/ruby_switcher.sh
Perhaps the script should have a function fetch_latest_ruby_switcher() ?
Awesome !
On my side, I installed manually the different version and write aliases in my .bash_login file who switch a single symlink to the different versions. For exemple :
alias use_ruby_187=’sudo ln -fhs /usr/local/ruby-1.8.7-p72 /usr/local/ruby’
alias use_ruby_191=’sudo ln -fhs /usr/local/ruby-1.9 /usr/local/ruby’
There also multiruby gem http://blog.zenspider.com/2007/12/testing-for-ruby-18-and-19-usi.html who makes a good job as well.
I’m not sure if this matters in 1.9 but you may consider adding the—disable-pthread flag during configuration which typically yields a 30% speed increase.
This is terrific (Although I did have a problem installing REE, and sent you the ‘relevance’ user on GitHub an email about that, a pointer to a bug tracker would be nice).
And you’ll be happy to note that I tested a gem project I manage and discovered a couple of tiny incompatibilities with 1.9.1 which are now fixed and the gem is tested in 1.8.6, 1.8.7, 1.9.1 and Leopard Ruby. I feel much better now. Thanks.
Some tips on using various ruby versions with Passenger/Textmate would be much appreciated.
@Andrew – Thanks. That issue is fixed in the latest version.
REE’s gems now live in: ~/.gem/ruby-enterprise/1.8
Commit: http://is.gd/2h2io
Latest Version: http://is.gd/2h2mD
@Glenn – I tried recreating the REE installation error on a clean OS X image, but I was unable to reproduce the problem.
Are you still seeing this problem?
Are their any custom permission settings for your user account? It seems odd that you wouldn’t be able to write to your own home directory.
I want to test my site with 1.9. when i type gem list it only have rake. Can I share my old gems or do I have to install all the gems? how do i install gems? can i use rake gems:install?
thank you!
Hi Jason,
I mentioned to you in GitHub email that the problem went away mysteriously (problem installing REE related to installation of memory allocator). I wanted to report that I did a clean install (erase and install, not upgrade) of Snow Leopard today on my laptop, and with nothing installed or configured other than XCode dev tools I saw the same error pop up when trying to install REE. The others installed clean. Cheers.
A note to passenger users—in addition to specifying your PassengerRuby, you’ll also need to specify a couple environment variables first:
Then you’d have something similar to this (this is what passenger-install-apache2-module feeds you):
Then passenger/rails seems to pick up the correct gems. (mostly, I’m still having issues with mysql)
If you do ‘install_ruby_186’ then once installed you have to manually download rubygems from http://rubyforge.org/projects/rubygems/ and install it using ruby_186 (use_ruby_186).
Anyone get this working with the sqlite3-ruby gem? That’s the last bit for me that is preventing me from running multiple versions side-by-side. The gem installs fine, however, when I try to require it I get an error:
<internal:gem_prelude>:234:in `push_gem_version_on_load_path’:Gem::LoadError: Could not find RubyGem sqlite3-ruby (>= 0)This happens when starting up a Rails app which relies on sqlite3-ruby although the rails app still starts fine after this. I cannot run any tests though.
@Dan – You don’t want to share your old gems. Just install new gems after switching to the desired Ruby version. “gem install some-gem-name” will just work. And yes, for Rails projects, just “run rake gems:install”.
@Justin – Which Ruby versions are having issues with the sqlite3-ruby gem?
I thought the only thing needed to switch between ruby versions is just changing an environment variable or two (e.g. RUBY_PATH, RUBY_LIB_PATH) and referencing that in other places (e.g. PATH). The real trick is getting gems and configuring servers.
What exactly does the Ruby Switcher do different?
Thanks, this really helped. Your blog post is actually referenced within a RoR course!