Installing Ruby 1.8 and 1.9 Side by Side
It’s unfortunate that people are still having trouble getting Ruby 1.8 and 1.9 to co-exist on a single system. It’s unfortunate because it hurts the migration and adoption rate of Ruby 1.9. That’s specifically unfortunate because Ruby 1.9 is insanely better than 1.8, so much so that I honestly think that people not wanting to switch might actually be insane themselves.
If you’re thinking about trying Ruby 1.9 but think it will be a hassle to install and will break all your (non-rails) apps, read on. I use Ruby 1.9 almost exclusively and have very few issues.
Part of the blame can be laid on the lack of information out there about getting these two installs working side by side. The information that is out there is further diluted by here-say that it’s “difficult” or gems like multiruby that are difficult. The other part of the blame can be laid on RubyGems, which actually makes it difficult to have these two Ruby’s co-existing.
The truth is, getting Ruby 1.8 and Ruby 1.9 living side by side is actually ridiculously easy, and making RubyGems work right is now even ridiculously easier.
Installing Ruby 1.9
Don’t be afraid. What we’re doing here is going to leave the smallest footprint on your machine possible. Brian Cardarella summed this up nicely on his blog.
your-ruby1.9.1-dir$ ./configure --program-suffix=19
That’s it. You can now
make && sudo make install and have Ruby 1.9 working
ruby19. But you probably want programs to know about your Ruby, so you’ll probably want to symlink it.
You don’t need to do it this way, but this is how I got everything working. I moved all my ruby, irb and gem executables to use the 18 suffix manually:
sudo mv /usr/local/bin/ruby /usr/local/bin/ruby18 sudo mv /usr/local/bin/irb /usr/local/bin/irb18 sudo mv /usr/local/bin/gem /usr/local/bin/gem18
The `gem` binary is likely to use the ruby binary with the suffix attached. You'll want to edit the shebang and remove the suffix. This is likely the last time you will need to edit a file
You can now symlink
gem to whichever Ruby you want to use. In my case, I want Ruby 1.9, so:
$ sudo ln -fs /usr/local/bin/ruby19 /usr/local/bin/ruby ...
There’s an even easier way to do the symlinks. Simply install an alias in your
~/.profile. I use this:
alias ruby-switch-18='sudo ln -fs /usr/local/bin/ruby18 /usr/local/bin/ruby && sudo ln -fs /usr/local/bin/irb18 /usr/local/bin/irb && sudo ln -fs /usr/local/bin/gem18 /usr/local/bin/gem' alias ruby-switch-19='sudo ln -fs /usr/local/bin/ruby19 /usr/local/bin/ruby && sudo ln -fs /usr/local/bin/irb19 /usr/local/bin/irb && sudo ln -fs /usr/local/bin/gem19 /usr/local/bin/gem'
Which lets me do:
~$ ruby-switch-18 && ruby --version ruby 1.8.7 (2009-01-28 patchlevel 99) [i686-darwin9.6.0] ~$ ruby-switch-19 && ruby --version ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin9.6.0]
Getting RubyGems to Make Sane Executables
The other problem you’ll eventually run into is that RubyGems likes to rewrite the shebang when it generates executables in a
gem install to use
ruby19 (now that you’re using suffixes). We just want it to use
Now I said this was easier. It is. Install this gem:
sudo gem install gem-sane-binary
You can see the source on Github. It’s a small RubyGems 1.3.2+ plugin that uses your
ruby symlink (if it exists) instead of the current Ruby executable when generating binaries.
You can now
gem install anything without worrying about having it break your other Ruby install.
If you’re an OSX user, this one’s for you:
Now that you’ve switched over to 19 you might be interested to know how to get some of your apps that depend on Ruby to work properly. TextMate has some decent 1.9 support so far, but you need to pull the latest support code from the subversion repository:
cd Library/Application Support/TextMate/ svn co http://svn.textmate.org/trunk/Support/
If you use the Git textmate bundle, read about how I got it working in 1.9 here.
Note that with our quick switch alias, if anything breaks you can always `ruby-switch-18` in a Terminal to quickly drop back. TextMate need not be restarted.