Friday, May 15, 2009

Tip: Compiling the Postgres Gem for Ruby 1.9.1

[EDIT (2010-JAN-16): The original postgres gem has been replaced by ruby-pg. If you are having the problem below, try installing the pg gem via sudo gem pg install.]

Crash!

I compiled a fresh copy of Ruby 1.9.1 onto my MacBook Pro and proceeded to install Ramaze, Sequel, Thin. Things went well and I was happy... that is, until I tried to install the postgres gem. I'm talking the C-extension one, which runs so much faster than the native one that it isn't even funny.

$ sudo gem install postgres

That's when it happened: bam! exception!

/usr/local/bin/ruby extconf.rb install postgres
extconf.rb:4:in `<main>': uninitialized constant PLATFORM (NameError)

No good. How am I supposed to develop enterprise Ruby software when I cannot connect to the database?!

What Happened

After poking around on the internet, I discovered two things about Ruby 1.9.1:

  1. The PLATFORM environment variable is now RUBY_PLATFORM, and
  2. The C macros for working with a Ruby Array changed.

The Solution

To solve this problem, one could learn what to do and hand-change all the code. This is a waste of time. I set-up a couple sed filters instead. Thus, to get your postgres adapter working, just do the following:

$ cd /usr/local/lib/ruby/gems/1.9.1/gems/postgres-0.7.9.2008.01.28/ext
$ sudo sed "s/PLATFORM/RUBY_PLATFORM/" extconf.rb > ./extconf.rb
$ sudo ruby extconf.rb
$ sudo sed "s/RARRAY(\([_a-zA-Z0-9]*\))->ptr/RARRAY_PTR(\1)/; s/RARRAY(\([_a-zA-Z0-9]*\))->len/RARRAY_LEN(\1)/; s/row->len/RARRAY_LEN(row)/; s/row->ptr/RARRAY_PTR(row)/" postgres.c > ./postgres.c
$ sudo make
$ sudo make install

Disclaimer

While I have been successfully using this patch, I have not tested it in a production environment. Therefore, you should put this patch through its paces before using it on anything critical.

Lastly, but definitely most importantly, I am NOT liable for anything bad that may happen as a result of using this patch. It is up to you to thoroughly test it for any problems, which may include (but are not limited to) loss of data on your system, loss of data on your database, corruption of your Ruby installation, self destruction of your hard drive, spontaneous combustion of your printer, Swine flu infection, SARS transmission, broken lawn mowers, and rancid ice cream.

Tip: Ruby 1.9.1 RDocs in HTML

That's A Big Process!

I like my HTML RDocs. They are easy to browse and search. Unfortunately, unlike ruby 1.8.x, which made compiling the HTML RDocs trivial, ruby 1.9.1 seems to only make ri documentation trivial... and I soon found out why.

It turns out that on my old MacBook Pro (maxed out with only 2 GB of RAM), I didn't have enough RAM to build the process. Somewhere around 3/4 of the way done, the thing would jump into swap and crawl to a halt. I aborted and decided I'd have to live with online and ri documentation.

Recently, however, I upgraded to a new MacBook Pro with 4 GB of RAM on board and decided to try compiling the RDocs again. After 25 minutes and around 2 GB of RAM for the single ruby process, it worked! (Why it takes so much RAM is beyond me... they need to rethink how RDoc is written).

Where Do I Get It?

Considering that I've gone through all the work, there is no reason why I can't share, so I've published the directory to my GitHub account in the ruby-rdoc project.

While other GitHub users will probably just clone the repository to keep up on the latest updates, most people will want to download a tarball or zip archive. To do this, simply go to the downloads page and pick the documentation that goes with the ruby version you want.