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.

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.
I've developed a very simple webapp.RequestHandler subclass that does a couple of useful things that I need in my GAE app. They seem like pretty basic things that are worth sharing – though anyone could have done it themselves in five minutes.

class BBRequestHandler(webapp.RequestHandler):
  # Render a template with standard data mixed in.
  def render(self, template_name, template_data = {}):
    template_data.update(self.sundries())
    self.response.out.write(template.render('view/' + template_name, template_data))
  
  # Forward the request to a different handler. Assumes GET.
  def forward(self, handler_class):
    handler = handler_class()
    handler.initialize(self.request, self.response)
    handler.get()
    
  # Standard template data required for most pages.
  def sundries(self):
    return {'logout':users.create_logout_url('/')}

The intention is that sundries() should return whatever standard data your pages require that's not specific to individual pages. In my case that's data that's required for the header, footer and sidebar – like the logout URL.

You may notice that I'm not using the Python docstring format. I just can't quite bring myself to do that just yet, though I have got used to the indentation-is-block thing.

I've noticed that a lot of the standard Python methods on lists and dictionaries don't return anything at all – they simply modify self and return nothing.

>>> l = [1,2,3]
>>> r = l.reverse()
>>> print l
[3, 2, 1]
>>> print r
None

This is becoming extremely frustrating as it prevents chaining of method calls, which would be possible if only self was returned. This keeps catching me out if I attempt to return some_list.reverse() or dict = {'foo':bar, 'x':y}.update(some_other_dict) as I end up with None when I expected Something.

It's the little details that make a language a joy or a chore.