Dec. 19, 2008 Update: This post covers setting up and switching the default Ruby installation in /usr/local. If you're looking for a more dynamic way to test and/or switch between Ruby versions see Switching Between Ruby 1.8 & 1.9 with multiruby.

I had originally installed Ruby 1.8.6 on Tiger from source using Dan Benjamin's Building Ruby, Rails, Subversion, Mongrel, and MySQL on Mac OS X instructions. I upgraded to Leopard but continued to run the /usr/local version of Ruby. It has been working fine for me but for various reasons I decided it was time to upgrade to 1.8.7. I was happy to see Dan had created updated instructions for Leopard in his Installing Ruby, Rubygems, Rails, and Mongrel on Mac OS X 10.5 (Leopard) post. So I decided that I'd just install over my 1.8.6 version. It didn't go off without a hitch, I ran into a problem compiling readline. This post documents what worked to resolve the problem, my journey back to 1.8.6, how to add 1.9 support and how to switch between versions.

ruby-1.8.7-p72

My first step, and original goal, was to upgrade to 1.8.7. Since I already had 1.8.6 in /usr/local I already had RubyGems so I thought I just needed to follow the Ruby installation instructions. Here's a repeat of Dan's information about how to do that:

$ cd /usr/local/src
$ curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
$ tar xzvf ruby-1.8.7-p72.tar.gz
$ cd ruby-1.8.7-p72
$ ./configure --enable-shared --enable-pthread CFLAGS=-D_XOPEN_SOURCE=1
$ make
$ sudo make install
$ cd ..

But the instructions were for a fresh Leopard install and I ran into the following problem during the make:

compiling readline
gcc -I. -I../.. -I../../. -I../.././ext/readline -DHAVE_READLINE_READLINE_H ...
... -D_XOPEN_SOURCE=1  -fno-common -pipe -fno-common   -c readline.c
readline.c: In function ‘filename_completion_proc_call’:
readline.c:703: error: ‘filename_completion_function’ undeclared
     (first use in this function)
readline.c:703: error: (Each undeclared identifier is reported only once
readline.c:703: error: for each function it appears in.)
readline.c:703: warning: assignment makes pointer from integer without a cast
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared 
     (first use in this function)
readline.c:730: warning: assignment makes pointer from integer without a cast
{standard input}:358:non-relocatable subtraction expression, 
     "_mReadline" minus "L00000000007$pb"
{standard input}:358:symbol: "_mReadline" can't be undefined in a 
      subtraction expression
...
{standard input}:249:non-relocatable subtraction expression, "_completion_proc"
       minus "L00000000003$pb"
{standard input}:249:symbol: "_completion_proc" can't be undefined in a 
        subtraction expression
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1

I went through a couple of failed correction attempts based on posts from others before finding Angelbob’s Musings on Programming, Compiling Ruby 1.8.7 on a PowerBook G4 with Mac OS X 10.4 post. Bob's post explains that the issue relates to which version of readline you're using and Ruby not knowing whether functions have an "rl_" prepended to function names but that you can explicitly provide the information in Ruby's config.h. Since I'd messed with the 1.8.7 source directories I deleted the whole thing, extracted it again and then, after re-running the configure command, I added the following to config.h:

193
194
195
#define HAVE_RL_FILENAME_COMPLETION_FUNCTION 1
#define HAVE_RL_USERNAME_COMPLETION_FUNCTION 1
#define HAVE_RL_COMPLETION_MATCHES 1

This time the make and installed worked fine. I could have left it at that but since Dan's instructions would have worked with a fresh Leopard computer I decided to get rid of the /usr/local readline version that I had installed back when I was running Tiger. I didn't want to deal with non-standard (meaning non-native to Leopard) readline issues again. First I made sure I didn't have other /usr/local/ readline dependencies, I didn't; in my case readline 5.1 was only installed to get the orignal Ruby 1.8.6 environment set-up, so I nixed it:

$ cd /usr/local/src
$ cd readline-5.1 
$ sudo make uninstall

From there I started again over with Dan's Leopard instructions. This time everything worked without modifying the config.h.

1.8.6-p287

Unfortunately I couldn't stick with 1.8.7. Mephisto is using 2.0.2 and starting it in 1.8.7 results in this error:

undefined method `[]' for #

So, I moved back to Ruby 1.8.6. This time I got the latest version and dropped the use of the /usr/local readline:

$ cd /usr/local/src
$ curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p287.tar.gz
$ tar xzvf ruby-1.8.6-p287.tar.gz
$ cd ruby-1.8.6-p287
$ ./configure --enable-shared --enable-pthread CFLAGS=-D_XOPEN_SOURCE=1
$ make
$ sudo make install
$ sudo make install-doc
$ cd ..

1.9.1-preview2

Other than the 1.8.7 and Rails incompatibility everything was fine and, since switching between installations was now fresh in my mind, I decided it was finally time to try the latest 1.9 release:

$ cd /usr/local/src
$ curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-preview2.tar.gz
$ tar xzvf ruby-1.9.1-preview2.tar.gz
$ cd ruby-1.9.1-preview2
$ ./configure --enable-shared --enable-pthread CFLAGS=-D_XOPEN_SOURCE=1
$ make
$ sudo make install
$ cd ..

After I'd done a little testing going back to 1.8.6 was easy:

$ cd /usr/local/src/ruby-1.8.6-p287
$ sudo make install
$ sudo make install-doc

So, with the readline issue gone, I can switch my default installation by just changing to appropriate build and running "sudo make install" (and "sudo make install-doc" for pre 1.8.7 releases) whenever I want.

I should add a caveat at this point, it's generally been fine to install Ruby over old versions and I didn't notice any problems but there is a chance that a file from a previous install won't get overwritten and could cause a problem. Also, my goal was just to upgrade, it wasn't to come up with an optimal or clean way to switch between versions.

Sorry, comments are closed for this article.