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!

A couple more shots from Vienna – now a few weeks back.

First, to prove that it was proper cold, here's a gargoyle with a not-so-runny nose.

ViennaGargoyleIce

And in an arty mood, here's Vienna through the bottom of a beer glass – which is shockingly very nearly empty!

ViennaThroughBeerGlass

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.

The dome of the Stephansdom cathedral in Vienna is a cracking example of baroque excellence. Here is the view straight up. Right in the very centre of the ceiling of the lantern is a dove.

AustriaCathedral
This dove in the very centre, on the ceiling of the lantern above is very similar to that at the pinnacle of Karlsdom below, but we were able to get within a few feet of the Karlsdom version courtesy of the slightly rickety scaffold reaching up all the way into the heavens.
ViennaKarsldom
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 nipped down to the local nature reserve today and it really felt like Spring had sprung. After the recent spell of miserable, cold weather, today was balmy and glorious with the smells of growing plants on the gentle breeze.

The wildlife was enjoying it too, with the resident kingfisher doing what he does best – fishing. One thing he doesn't usually do at all is come anywhere near me so I can get a really good photograph. Today though, he flew to a nearby branch and sat posed in the sun for 15 second or so. I can tell it was definitely a he as the bill is all black. This is my best shot yet of a kingfisher, by some margin.

KingfisherBig

This is quite a special lager – brewed with champagne yeast it has a very fine, light bubble and it does indeed taste like a beery champagne. Imagine a very fine champagne with the sweetness replaced with dry pils bitterness. Certainly the lingering feel in the mouth is more champagne than beer.

There are very few beers brewed in this style, so this one from Alsace is quite unique and worth tracking down. I was spurred to pick some up because Waitrose had 25% of the bottles – and it was on taste :-) It's really very good indeed – super refreshing and drinkable (but remember it's a deceptive 5.2% ABV) but a bit unusual.

In this case I was drinking it from a K├Âlsch glass, which isn't entirely right, but seemed to suit it's delicacy. I suppose it could/should be drunk from a champagne flute!

KasteelCru
The theory is good with the new buttonless MacBook trackpads, but in practice I think it’s flawed. The whole very large surface clicks down when pushed, though it’s hinged at the far side, so it works best at the side closest to the user. So you ought to be able to use your thumb to click exactly where the button used to be, and be no worse off than before. Problem is, the button was raised up a bit above the palmrest, whereas the tracking surface is a shade below it. So now your thumb has to reach down and over the lip to click, which is a bit uncomfortable. It’s a subtle difference but I think an important one.

I’ve only had a play in the shop, so maybe I’d get used to it and maybe even change my clicking habits entirely, but it put me right off.