Spurred on by Antonio Cangiano's recent campaign, I've been trying to make a permanent move to Ruby 1.9.1. I've been on 1.8.6 by default for a good while, as that's what you get with Mac OS X 10.5, though it's actually not too hard to get going compiling your own Ruby from source – no special tricks are required and it works great. I hope Apple makes 1.9.x the default for OS X 10.6 when it appears later this year. Go on – be brave!

So what have I found in this exciting new world?
  • It's a bit faster, as expected, though nothing to get especially excited about.
  • Some very popular gems just don't work straight off the shelf. Mongrel for instance – though I'm told it's really easy to get it working with a couple of tweaks. Still, it's a shame for the sake of the community that the official latest gem can't have those tweaks made to it and save a lot of people an awful lot of fuss. Actually I hear that Mongrel 2 is on the way, taking advantage of more of Rack's infrastructure. I look forward to it. 
  • ri now works really quickly compared to my 1.8.6 install, which always thinks for a couple of seconds before giving me a result. I think this is due to a new caching mechanism that was introduced around 1.8.7. Simple things like this make a huge difference to my life!
  • ri actually finds docs for the standard libraries, which it didn't for my 1.8.7 install. I think was due to some issue in the standard makefile for 1.8.7, but I'm not really sure. Again, for someone like me who only just knows what he's doing, this makes a huge difference.
  • Proper string encoding support! Finally the promised land, as long as you can take the hit of string indexing now being incredibly slow.
  • Rubygems at 1.3.1, which is much more refined than that bundled with ruby 1.8.6 on Mac OS X. You can get this for yourself on any version of Ruby with gem update –system BTW. No more "Bulk updating Gem source".

I recommend everyone tries to move on up, at least with a parallel install that they can easily switch, and applies pressure to the holdouts to get it happening. Commercial pressures will make it tough for many, but when we break on through to the other side it will all be worth it I reckon. 

Update: There is a new effort to create a decent Windows Ruby installer. You can get the new downloadable installers from http://rubyinstaller.org/ though as of August 2009 these are still in preview form. It seems from my brief experiment that you'll still have to set your PATH manually, as per my manual instructions below. This installer also promises a faster Ruby as it builds using superior tools, so might well be worthwhile if only for that. Below are my original manual instructions for installing Ruby on Windows, which should still be just as valid as they always were. The installer is probably worth a look though.

The following worked for me on Windows XP, but maybe I'm yet to run into problems I don't know I've got:

That got ruby working in a basic sense for me, but I wasn't able to install gems. If I tried, I got two errors in sequence: "The ordinal 277 could not be located in the dynamic link library SSLEAY32.dll" and "This application has failed to start because zlib.dll was not found."

The ssleay32.dll problem was solved by getting hold of a couple of DLLs and putting them in the right place, as follows:

  • Download "Win32 OpenSSL v0.9.8k Light" from http://www.slproweb.com/products/Win32OpenSSL.html.
  • Run the installer, but take note of the following:
  • You can ignore any initial warning about not having Microsoft Visual C++ 2008 Redistributables.
  • You can ignore any warnings about command prompts being open.
  • Install to somewhere like C:\OpenSSL – it doesn't really matter, we just need a couple of DLLs.
  • When prompted, choose to Copy OpenSSL DLLS to The OpenSSL binaries (/bin) directory.
  • Once the installer has completed, you can go to C:\OpenSSL\bin (or wherever you installed it) and copy the two files ssleay32.dll and libeay32.dll to your Ruby bin directory, C:\ruby191\bin in my case.

The zlib.dll problem was solved by in much the same way:

  • Download the compiled zlib 1.2.3 DLL from http://www.zlib.net/ (about two thirds of the way down the page).
  • Unzip it to get the zlib1.dll file.
  • Put that file in your Ruby bin directory, but rename it to zlib.dll

Et voila – gems can now be installed successfully! Note that you may have had copies of some of these DLLs in your \WINDOWS\system32 directory already (I certainly did) but the problem is that they are too old. I prefer to put the newer ones directly in the Ruby bin directory, so only Ruby picks them up and it can't break anything else on the system.

Rather mysteriously, my bluetooth mouse suddenly stopped responding with no warning. I assumed it was duff batteries, though I'd normally get a warning a good while before they conk out completely. Changed them, but still no dice. I attached a wired mouse and did some digging – basically Bluetooth no longer seemed to exist on my Mac! The menubar widget claimed bluetooth was 'not available' and the System Preferences Panel said similar. Restarting didn't help – in fact it made the menubar widget and System Preferences Panel disappear entirely!

After a bit of digging on the web, what worked for me was to reset PRAM. Shutdown computer, then start it up whilst holding down cmd-option-P-R until it chimes a second time. Actually I held down until a third chime for good luck. Seems to have done the trick!

Update: It then failed again shortly afterwards. Next move was to delete a critical prefs file. Best not to do this unless you have a clue what it means:
  • sudo mv /var/root/Library/Preferences/blued.plist ~/Desktop/

At the same time I shutdown the computer, removed all attached cables, opened it up and pressed the PMU/SMC reset button down near the RAM (this is a PowerMac G5 tower) then restarted. It seems to be OK for now. It did mean the clock resetting to 1970 and me having to wait for all my iCal notifications to stream in once I'd reset to 2009.

Update 2: And it's gone again. Maybe it'll never be back. I swear if Apple sold some sort of mid-tower machine – somewhere between an iMac (but without a screen) and the Mac Pro, I'd buy one without a second's hesitation. I've been waiting for years for this machine, on the assumption that it's an obvious hole in their line-up and will be along any moment, but I've been hideously disappointed.

Update 3: It seems that if I shutdown the computer rather than simply restarting, my bluetooth comes back to life. At the moment it's been fine for all of today, but it might flake out on me at a moment's notice for all I know.

Update 4: Correction – resetting PRAM by holding down cmd-opt-P-R until you hear a second chime is vital. Simply shutting down and restarting does not seem to do it. At the moment I sometimes get a few days of successful use between failures.

I've been experimenting with Ruby 1.9.1 and trying to make it my natural home recently. Crucial to that was getting the mysql gem installed. Actually it's fairly straightforward with the 2.8.1 version of the gem and only very minor mods to the official instructions at http://www.tmtm.org/en/mysql/ruby/ were required.

Note that I have only tried this to work against MySQL 5.0.x, which I have installed in /usr/local/mysql, as all my previous attempts to use MySQL 5.1 have failed miserably and I've given up on that for now. These instructions install from source, resulting in a fresh /usr/local/ruby191/lib/ruby/site_ruby/1.9.1/mysql.bundle. Then you can simply require 'mysql' in your Ruby code and you're away.

  • Downloaded 2.8.1 source tgz from RubyForge, linked from http://www.tmtm.org/en/mysql/ruby/ downloads section.
  • Expanded the tgz with Finder, then opened a command prompt…
  • > cd mysql-ruby-2.8.1
  • > ruby extconf.rb –with-mysql-config=/usr/local/mysql/bin/mysql_config -with-mysql-dir=/usr/local/mysql
  • > make
  • > sudo make install
Et voila! Note that make did output a bunch of warnings about implicit 64/32 bit conversion that suggests the code isn't entirely 64 bit happy, but I've not observed any problems as a result. Yet.

I advise every programmer out there to read lots of other people’s code. Pick an open source project that you’re a fan of (and perhaps use every day), download the source and then sit and try and figure out how it works. You may find the following things:

  • It’s interesting to see how other people write code, from their specific syntactic style to the level of commenting, overall design and code layout, common idioms etc. You’ll probably learn something – either good things that you can copy, or bad things that are tough to read and warn you off doing the same.
  • You may find the code frustrating and difficult to figure out, not only initially but no matter who long you work through it, though if that’s the case then it’s probably poor code. Hopefully that will influence how you write your own code, for the better. 
  • If it is a product that you use regularly, you may gain insights into what it’s really doing and how, that empower you to use it more effectively. You may even be able to modify it to make some improvement that matters to you.
  • Once you’ve got past the initial difficulty and started to understand things, you acquire a sense of power. No longer are these complicated pieces of software opaque and mysterious. They can be broken down, understood and messed with. A whole world of possibilities opens up and you no longer need to be afraid. 

I’ve recently been reading the Ruby source code of Innate – the new underpinnings of next generation Ramaze, a Ruby web app framework that I particularly enjoy using. Innate is built on top of Rack, so I’ve been reading that too. The mystery is ebbing away and it’s making me more powerful. Stand back! 🙂

I'm currently at QCon in London, with a couple of hundred other software developers. I've already seen Sir Tony Hoare's keynote and learnt some more about making Agile work in the real world. I was lectured by Sir Tony at University as it happens – and he's much as I remember him, complete with the slightly unexpected doses of wry amusement.

I've been following the progress of MacRuby for a few months now and was looking forward to the next release. Finally, and a month or three after it was expected, MacRuby 0.4 is here, according to the MacRuby blog.

MacRuby is, to keep it simple, an implementation of Ruby 1.9 built in Objective-C with transparent calling between the ruby and Obj-C worlds. For instance Ruby Strings are actually NSStrings in MacRuby and have all the powers of both. This along with some other neat integrations provided by the team allow you to write Mac OS X Cocoa apps using Ruby instead of Obj-C, or even a combination of both. If like me you think that Obj-C is a dinosaur that doesn't deserve a place in the modern programming world, this is great news. There seems to be a lot of momentum behind this project and I wonder if it may eventually become quite a fully fledged citizen for Mac app programmers – maybe even ultimately taking over from Obj-C for most Mac OS X development. I can but hope.

One of the many neat improvements in 0.4 is the ability to bundle the MacRuby runtime into the app itself so the user need be none the wiser, and certainly doesn't need to install MacRuby.

I was running into an annoyance whereby I'd end up with duplicated validation messages from ActiveRecord. I tracked this down to the source reload feature of Ramaze, which was reloading my AR model classes each time I edited them with the dev server running, which has the unfortunate side effect of adding the validators again on top of the same ones that were there before. So each reload adds another set of validators and another duplicate validation message. This sort of thing (mainly class methods that add to a list) often requires special care when working with a source reloading system. In this case I've worked around it by resetting AR's internal validator list to empty before creating my validators, by directly accessing the @validate_callbacks instance variable. For example:

class Event < ActiveRecord::Base
    # Clear all AR validations, to avoid getting duplicates on source reload.
    @validate_callbacks = []
    validates_presence_of :name
    validates_presence_of :description
end

Did you know that you can simply type "gem server" at your command line to start up a web server on port 8808 that presents all the built-in documentation for your installed gems?

This seems to be a little known fact among Ruby programmers, but worth a lot I reckon. I have rediscovered this feature a couple of times and it's enormously useful, especially when working on the train so having to rely on local documentation. It certainly beats ri for many things.

Picture 6
Oh and that's the new Safari 4 beta, if you're confused by the look of the browser window in this screenshot!

I've been furiously porting my Ramaze CRUD helper from DataMapper to ActiveRecord and I've been quite surprised to find that it's only taken a couple of hours. I should hastily point out for non-programmer types, that CRUD stands for Create Read Update Delete – the four basic operations you can perform on a data entity.

My helper makes it super-easy to produce basic CRUD web pages for any data entity, with just a couple of lines of code in your helper – a bit like Rails scaffolds but without the scaffolding! Sounds like magic, I hear you yell! Well yes, but it's my magic that I wrote from scratch so it's not magic to me 🙂

It's been an easy port between ORMs mostly because the concepts and syntax map over with relatively little fuss, and actually 98% of my CRUD helper code is not concerned with the DB, but rather with running the web UI. So the few places that actually perform a DB operation needed a bit of tweaking to use the right syntax, but it's been pretty smooth sailing. Hopefully it will be easier with AR to neatly deal with many-to-many associations without having to explicitly fool around with the join table. We shall see, as that's what foxed me with DataMapper and caused me to switch.

One very important thing to mention is that when using ActiveRecord outside of Rails you have to know that it was originally written for the single-threaded Rails world. Hence it just maintains a very small connection pool (say 3) and those connections quickly run out in a threaded environment – Ramaze in my case. This leads to strange pauses of several seconds as your request handling thread waits for a connection to come free. They come free after about 5 seconds of inactivity, so you get one reasonably soon, but the multi-second pause is infuriating and very confusing. A neatly packaged solution is handily presented and well explained here: http://coderrr.wordpress.com/2009/01/16/monkey-patching-activerecord-to-automatically-release-connections/. Note that there is a link at the bottom to the single-file patch that just sorts everything out for you, so if you can't be bothered to read the explanations, head straight for that, require it in your project and you're away.