Why migrate to only Ruby 1.9?
Ruby 1.9 (and beyond) is the future of Ruby. It is allegedly around twice as fast as Ruby 1.8, which confers both performance and cost saving advantages (the ability to serve the same number of users in less CPU cycles.) My impetus for upgrading to Ruby 1.9 turned out to be a bug involving the Time object, specifically Time.local returning a time that was off by one second. Also, the time zone parameter to Time.local became invalid by a newer build of Ruby 1.8.7; this caused concern that my client's Rails app would break when the version of Ruby 1.8.7 on his Debian 6 server is upgraded to the same or later build number. After logging into the Ruby Issue Tracking System to report the bug, I was confronted with the following instruction: "Try at latest version - If you using Ruby 1.9.2-p0, Install Ruby 1.9.2-p136 (It's maintenance release) and try on it." I read the writing on the wall and decided it was finally time to move forward. Acquantances who had been using Ruby 1.9 convinced me it was safe to use. I'm finding my Ruby 1.8 code to be almost 100% compatible with Ruby 1.9; so far I've only had to change a few object methods and parameters. I usually don't stretch the limits of a language, so your own results may vary.
The first step in my new strategy, was to get rid of all traces of Ruby and Gems from the Debian system. This was easy enough using a combination of apt-get remove --purge of all Ruby packages and rm -rf of the directory trees where I had installed my gem utility when building it from source. I then installed Ruby 1.9 using APT, and quickly discovered it didn't work. After installing the ruby1.9 package on one of my machines running Ubuntu 11.04, ruby -v revealed itself to be version 1.8.7! After reading reports that Debian packaging of Ruby has been problematic, I finally decided to build both Ruby 1.9 and Gem from source code. I was pleasantly surprised to learn that Ruby 1.9 includes Gem and other utilities in the same source tree and installs them intelligently in the same directory tree as Ruby 1.9 during the make install step. Placing Ruby utilities and gems within the same directory tree as Ruby 1.9 greatly simplifies management of the Ruby environment.
Some Debian and Ubuntu purists may disapprove of building utilities from source. I understand that at some point the utilities may break, either because of Linux kernel upgrades, shared library upgrades or new library requirements when compiling a newer build of the utilities. My first choice is to use Debian package management, but if that doesn't work when it comes to something as important as Ruby 1.9 for a server with a sole purpose of running a Rails application, I see managing the dependencies myself as the only viable alternative, testing upgrades first on a separate sandbox system before deploying them to production servers. A deployment tool such as Capistrano can be used to push these new Ruby 1.9 builds to many systems.
If after performing due-diligence you decide to follow the same strategy I did, the next phase is to go ahead and try it. These are the steps I used to install and configure Ruby 1.9 and rubygems on a Debian server. I used the same method for installation on one of my local Ubuntu development machines:
Remove Ruby 1.8
If you wish, you can first remove all traces of Ruby1.8 and rubygems from the build system. This step is optional, because you will likely end up specifying a PATH directory different than what you are currenty using and if not will end up with a symbolic link pointing to the new Ruby 1.9 base directory. One of the nice aspects of Ruby 1.9 is that the gem utility lives in the same directory as ruby, with all gems residing within that directory tree. If you currently have ruby in a common directory such as /usr/bin, you can add the new ruby directory to the front of your PATH variable, making it the first location used to locate ruby, though you really should just go ahead and remove the old ruby from any such common locations. People use different methods and placements for ruby and rubygems, so I can't tell you exactly how to get rid of Ruby 1.8 and gems from your current system, other than saying that you use a combination of apt-get remove --purge of all Ruby packages and in those cases where you built from source rm -rf of the directory trees where you installed the builds. If you included any non-standard directories in you PATH environment variable or defined any special env variables, you will want to also remove those definitions from their configuration files.
Install Debian libraries needed to build Ruby 1.9
Login to the root account, then install the following Debian packages:
Get the source code for Ruby 1.9 and extract it
cd to a directory where you can build the software, then get the source code and extract it:
cd into the source directory, then build and install Ruby 1.9
Create a symbolic link in the deployment directory
Add new ruby bin directory to PATH variable in both the .bashrc and .profile files, for root user and other users
Add the following line to both the .bashrc and .profile configuration files for both the root user and any other user requiring access to Ruby:
then either # source .bashrc .profile or log out and then log back in to an account where the config file change was made, for the new PATH definition to take effect. It is important that you add this new PATH definition for the root user, because root will need to know this when you run certain Ruby commands with sudo (such as installing gems.) If you want to give all users on the system access to Ruby, you need only place this PATH redefinition in /etc/bash.bashrc (/etc/profile references the PATH in /etc/bash.bashrc.)
Update the Gem utility
That's it, you now have a fully functioning Ruby 1.9 environment on your Debian or Debian-based system.
You can now install Rails or any other gems:
You will have to install other gems for Rails to work, such as mysql, mysql2, sqlite or whatever else your particular Rails application requires. If your Rails app uses Bundler, you can simply run install bundle.
Ruby 1.9.3 was recently released. The source code tarball is located at ftp://ftp.ruby-lang.....3-p125.tar.gz. There has been a change to the core routines, that has affected the debugger. You now have to perform some additional steps to use ruby-debug with Ruby 1.9.3. You can use the following shell script to perform these steps, just change the ruby source code path in the --with-ruby-include directive, to point to the directory where you have placed your ruby source code:
echo "Installing ruby-debug with ruby-1.9.3-p125 ..." curl -OL http://rubyforge.org/frs/download.php/75414/linecache19-0.5.13.gem curl -OL http://rubyforge.org/frs/download.php/75415/ruby-debug-base19-0.11.26.gem curl -OL http://rubyforge.org/frs/download.php/63094/ruby-debug19-0.11.6.gem gem install linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem ruby-debug19-0.11.6 -- --with-ruby-include=/Your_Ruby_1.9.3-p125_source_code_path/ rm linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem ruby-debug19-0.11.6.gem echo "Done."
Managing Future Ruby 1.9 Builds
This method easily accomodates any future Ruby 1.9 builds you may want to try. The rubydir symlink created in /usr/local/bin can easily change to point to a different ruby-1.9.2-pXXX or ruby 1.9.3+ build. Ruby 1.9 has been designed with this in mind, making it a more intelligent environment than Ruby 1.8. Yes, you will have to reinstall all your gems in the new ruby1.9 tree, but this is a small price to pay for the peace of mind that comes with having the option of falling back on a known good installation should things go wrong with the new version.
When building software from source, there is always the issue of possible breakage due to kernel upgrades (an area where Debian package management shines.) The libraries used by Ruby are quite stable at this point, reducing the chance of such trouble, but you should always test your Ruby build after a kernel update and re-build if necessary. I recently updated a Linux kernel from 2.6.32 to 2.6.38 without problems to my ruby-1.9.2-p290 build.
Using this approach, you can create a shell script that presents a menu allowing you to select which build of Ruby 1.9 you want to use. The script will change the /usr/local/bin/rubydir symlink, based on your choice. This is a simplified version of what RVM does. You will modify the script each time you build a new Ruby 1.9, adding the new build to the menu:
#!/bin/sh while : do cat << $ Select Ruby Version 1. exit 2. ruby-1.9.2-p180 3. ruby-1.9.2-p290 $ echo -n " Selection?: " read selection case $selection in 1) exit;; 2) rm -rf /usr/local/bin/rubydir; ln -s /usr/local/bin/ruby-1.9.2-p180 /usr/local/bin/rubydir;; 3) rm -rf /usr/local/bin/rubydir; ln -s /usr/local/bin/ruby-1.9.2-p290 /usr/local/bin/rubydir;; *) echo "\"$selection\" is invalid! ";; esac exit done
You can place this script at /usr/local/bin/rubyversion and do sudo chmod 755 /usr/local/bin/rubyversion to make it executable. You can then simply invoke it as rubyversion
Package management purists may scoff at this approach, but it has advantages. First, when it comes to Ruby 1.9 this approach actually works, and works well. It requires you to understand the dependencies and structure required for your Ruby 1.9 environment. As a serious Rubyist, you are better off understanding these details. It is good practice to build and test a new Ruby environment on a separate development system before upgrading your production servers. Such practice mitigates the potential risk of breakage after a kernel update. You can comfortably run a Debian server within Virtualbox on an average dual-core laptop with 2 GB RAM, so you don't even have to dedicate a separate computer for your testbed. It takes quite a leap of faith to deploy new software on a production system before first testing it somewhere safe. While I have great faith in the Debian package maintainers, the problems I experienced with Debian Ruby packages led me to find an alternate solution.