Leopard Polish
Yes, I’ve upgraded to Leopard. Yes, it’s spiffy.
The headline features like Time Machine are great, but I’m loving the little details more.
For instance, the first time you go to run an application that’s been downloaded from the net, a dialogue pops up reminding you that the file has been downloaded and asking if you want to trust it. It’s a nice bit of security, and it asks you the question at the right time.
Tiger asks a similar question, but it does it at entirely the wrong moment. What happens is that Safari stops and shows you a dialogue that says something like “The file you downloaded may contain an application, do you want to continue?”. Well, of course I want to continue, I’m surfing the web, not trying to run this new app. My reaction to this sort of dialogue is to think “I just don’t care about that right now, go away and stop annoying me!”.
The way it works under the covers is pretty neat too. With any luck the OS X Finder team will take a leaf out of its book and think about replacing those annoying .DS_Store files with directory metadata along the same lines. But I’m not holding my breath.
Time flies when you're enjoying yourself 2
It’s been a while since I wrote anything here, mostly because I’ve been indecently busy. Well, up until last Sunday when I managed to trip over a low wall in our garden and, in the process take off a large amount of the skin on my left shin. A mere flesh wound, but painful, embarrassing and it’s left me sporting what looks like a foot long, white, elastoplast. The worrying bit is that, when I went to get my wounds dressed, the nurse took one look at my bulk and demanded a urine sample. Which tested positive for glucose. For the second time in a year. So, interspersed with getting my dressings changed at the GP’s, I got a blood test and it looks like I’m diabetic.
Given my weight and what I understand about the workings of late onset diabetes, it’s not really surprising. I’m sure it’s better to get an early diagnosis than a late one, but it does rather give one pause for thought. Somehow I doubt I’m going to find it easy to change my diet and lifestyle; if it were easy, I would have done it already. I like food. I don’t like exercise – it’s a pain in the arse, time consuming and boring. About the only form of outdoor exercise I ever enjoyed was sailing, but the old adage that you can recreate the sensation of sailing by standing in a cold shower tearing up 50 pound notes is depressingly accurate and I simply don’t have the 50 pound notes to spare.
Crap.
Anyway, normal blogging service should be resuming shortly; I’ve got a couple more nouns to write up as essays, and a long, half written, tutorial on writing pidgins in Ruby. Watch this space.
Rails tip: Side effect filters
Some bugs are easy to overlook. One that has a habit of catching me out is a Rails filter that returns false occasionally when it’s being evaluated purely for its side effects. Here’s how I’ve started working round the issue:
def side_effect_filter
return if some_conditions_not_met?
...
ensure
return true
endWhat happens here is that the ensure catches any return and returns true instead. The catch is that if something throws an uncaught exception anywhere, it too gets caught by the ensure and true is returned. Which may not be what you were looking for. Here’s how to fix that issue:
def side_effect_filter
error = nil
return if some_conditions_not_met?
...
rescue Exception => error
ensure
raise error if error
return true
endThis catches the exception in a rescue and stashes it in the error variable, then the ensure checks to see if an exception was thrown and rethrows it, otherwise, it just returns true. Which is bulletproof, but ugly. Let’s wrap the ugliness up in a method:
def self.side_effect(method, &block)
def_method(method) do
error = nil
begin
instance_eval(&block)
rescue LocalJumpError # catches an explicit return
rescue Exception => error
ensure
raise error if error
return true
end
end
end
side_effect :side_effect_filter do
return if some_conditions_not_met?
...
endAgain, not pretty inside, but all we actually care about anywhere else is that the interface is good and does what it’s supposed to do. Encapsulated ugliness has its own beauty. Especially if you get the interface right.
Homework
This should pluginize quite nicely, just install the method in ActionController::Base and ActiveRecord::Base and you have a very useful tool, but I’m still not sure that the method name is right, so I’m holding off on it. If someone were to come up with a bulletproof name and release a plugin, that would be wonderful though.
Updates
Fixed a scoping issue in the encapsulated version of the code. Replaced yield with instance_eval(&block)
Typo on Rails 2 1
Whee! Sat in my home directory is a version of typo that appears to work with Rails 2.0. I ended up giving up on the themer approach which proved to be very hard to get up and running transparently – things kept disappearing off around infinite loops, which is no fun at all, let me tell you.
So, ended up cheating and ended up monkeying with @@view_paths directly, which is almost certainly against the rules, but has the cardinal virtue of working.
I’m sanguine about it because the way themes worked on rails 1.2.x also involved fiddling with undocumented methods which aren’t there in edge rails.
So, it now remains to walk around the thing, kick the tyres, write a few more tests and generally get myself to the point where I’m happy that it all works, and merge my local branch with the main line. I’m going to wait until 2.0.0 proper has been released, but now that I’ve done the work I expect to be merging it sharpish.
Railsconf Europe Photos
I’ve finally started uploading the scans from RailsConf Europe last week. There’s still one more roll to scan and another 9 shots in the camera, but I’m pretty pleased with the results so far. I didn’t really start shooting until about halfway through the last day. The light in the hotel was horrible and I just wasn’t in the mood, then suddenly I’d shot three rolls and was wondering where I could find another roll of Neopan 1600 at 9pm in Berlin. It didn’t hurt that I found some really nice light (at least for a black and white photographer with fast film). The shot of James Duncan Davidson above was shot using one of the large LCD screens that were dotted around the hotel as a softlight. It’s the sort of trick that can cause endless pain when you’re shooting in colour, because the white balance is such a bear, but the magic of fast black and white film means I just didn’t have to care.
Later on, I found an even better lightsource – in the atrium there were columns with 3 or 4 big LCDs displaying conference information, which meant they were mostly white. I spent a chunk of the evening grabbing people and asking if I could take their picture in “The best light in the building”. I just wish I’d spotted it earlier in the day when there was more daylight as well, that really would have been gorgeous light.
Today's Noun is: Reticence 2
What does the OED say reticence is?
Reticence: Maintenance of silence; avoidance of saying too much or of speaking freely; disposition to say little.
Pretty straightforward. When I chose reticence as one of my five nouns for programmers it was another reminder that objects are not the same as datastructures. Well designed objects keep their cards (instance variables) close to their chest. Client code tells objects what to do, it doesn’t ask them to kiss and tell. In Smalltalk Best Practice Patterns, (you don’t have a copy yet? Are you mad?) Kent Beck recommends that you put your accessor methods in the private protocol unless you have a very good reason for indicating that the accessors should be used by clients by putting the accessors in, say, the accessing protocol or some other, more suitably named, protocol. (In Smalltalk, all methods are public, but you can and should organize them into protocols/categories, either by choosing some existing protocol, or coming up with a new protocol name). In less flexible OO languages, you should probably at least mark your accessors as protected unless you have the aforementioned very good reason.
What about parameter objects then?
One obvious ‘exception’ to the rule of reticence is the parameter object. Say you have an unwieldy method that takes a bunch of arguments and fills the screen with its implementation. Being a conscientious programmer, you want to apply the ‘composed method’ pattern to the method so you’ll still end up with a screen’s worth of code, possibly more, but the individual methods will be much more focussed in what they achieve. What stops you is that bunch of parameters which are used through out the method. So, you introduce a parameter object. Bundle up the parameters into a single object, replace each parameter variable in the body of the code with an accessor call on the parameter object, and have at it. You can extract methods easily and you’ll only ever have to pass a single object.
It’s tempting not to bother creating a ‘real’ object, it’s very easy to just use an options hash, a la Ruby on Rails. And, because the options hash is a common pattern through your code, you can start adding helper methods like with_options, and you’ll get an awful lot of leverage out of it.
However, what’s often missed in discussions of the parameter object pattern is that it’s a waystation, not a destination. It may be handy, but if you persist in treating it as a datastructure, you’re missing out on the good stuff. Now you have a parameter object, you can start to move behaviour onto the parameter object and before you know it you’ll end up with a real object doing real, testable (mockable?), work.
Homework
Find a method where you’re using an options hash. Try using that hash to build a parameter object and then apply the principle of reticence. What happens to it? Where does the behaviour go? If, like me, you’ve come to OO from procedural coding styles, making your objects reticent is not a natural thing to do, it can feel extremely odd. But the more you practice it, the better you’ll get at thinking in a truly object oriented fashion. Sometimes an options hash really is the way to go, but not as often as you’d think.
Try it, maybe you’ll be converted.
Slide Of The Conference 7
Britt Selvitelle of Twitter gave a cracking talk at RailsConf Europe about scaling Rails applications to Twitter scale. It was great. Full of advice that we shall definitely be taking on board as we continue to develop amazing tunes. However, the last slide before the inevitable “Any Questions?” was the slide of the conference. It read:
It’s 2007. Every spammer has your email address. Put it on your goddamn webpage so people can get ahold of you about interesting things
I was the only person in the room who applauded.
I’m enough of an old fart (I was 40 a couple of Saturdays ago. I don’t think I’m properly old, but, on the net it feels positively ancient) that I remember getting annoyed at people obfuscating their sender addresses so that I couldn’t simply hit r in rn to reply to them directly rather than wibbling on channel. This was especially annoying when I was replying with an answer to a question they’d asked.
In the (my stats tell me) unlikely event that you’re reading this directly on the webpage, you’ll see my email address, complete with mailto: link. The wayback machine tells me it’s been there since at least February 2006, I’ve been using the same email address, unobfuscated, on mailing lists, newsgroups, business cards and presentation slides for over 10 years now. Yes, I get spammed, so will you. So do you, I’ll bet. But I’ll pay the cost of making it easy for spammers if it also makes it easy for people I want to hear from to get in touch with me. Spammers are predictable; that’s why spamfilters work most of the time. Interested people – people who are prepared to send me relevant mail – are golden.
The marketing types will tell you that clicks cost money. Every screen your customer has to go through before you get her money is another place she could decide she has better things to do. And, presumably, she is going to get something tangible at the end of that process so she’s motivated to go all the way through the process.
Someone who wants to send you email has far less motivation than that. The reader who thinks, “Ooh, Piers has missed something there, but I the comment box is the wrong place to bring it up.” or “Ooh, Piers Cawley, I haven’t seen him since we were at university, I should drop him a line” will be far more likely to act on that impulse and send that mail if it’s one click away. If they have to go and google my address from an obscure newgroup, or crack pdcawley [at] bofh [dot] org [dot] uk, or some other fatuous scheme designed to hide me from bad guys who already know where I live…
You’re intelligent people; you know what’s going to happen.
Seriously, would it kill you to publish your contact details on your website?
Tangentially
One of the RSS feeds I follow is a technorati feed of blogs linking to Typosphere. It’s a reasonably good way of seeing what people are saying about Typo (even if it’s simply “I’m switching to Mephisto/Wordpress/Whatever”). However, a few days back, the feed told me that someone had said:
Sorry, comments are broken. Please send complains to Typo.
So, being a conscientious Typo maintainer, I thought I’d drop him a line and ask for a few more details to see if we could track down the root of his problem. No email on the page. No obvious pointers to an email address.
He might be paranoid on his blog, but he’s not paranoid enough to avoid spammers. I found his email on the first page of google results, but I only bothered to look because I was inspired by Britt’s slide to write this. I guess I should drop him a line and see if we can’t sort it out.
My head hurts 3
During DHH’s keynote at RailsConf Europe it was apparent that there’s a great deal to like in edge rails, so I thought I’d have a crack at getting Typo up on it.
Ow.
I’d expected the pain points to be related to routing, but it seems that the rails routing system is approaching the level of the Excel calculation engine – nobody dares touch it for fear of breaking things, so typo’s custom routes seemed to work quite happily. There were a few things that have been deprecated, pluginized or moved out of the set of modules that’s automatically included when you do a rake rails:freeze:edge, but they were pretty easy to sort – the deprecation messages are a good deal more informative now than they were last time went deprecation squashing. There’s a surprising amount of stuff that’s been removed without any deprecation warnings though, which isn’t very sporting. DHH said there would likely be a 1.2.4 release (possibly a day before 2.0) with a bunch more deprecation warnings covering everything that’s actually going away, so if you’re thinking of moving a maturish app to Rails 2.0 it might make sense to wait for 1.2.4, install that, squash warnings, and move on up to 2.0.
The real pain comes from themes. Typo’s themes rely on Rails internals working in a particular way, but they don’t work like that any more. In theory, the internals appear to be more theme friendly, related to allowing plugins to include views. The problem is, that it’s possible to change Typo’s theme without restarting the server, and the new themish internals don’t expect anything to change until the server’s restarted.
So, I’ve been playing with plugins. The most promising approach appears to be that of the themer plugin, which gets pretty close to doing what we need, and does it in a way that seems like it should work with both 1.2.3 and Edge Rails. It does appear to be making some radically different assumptions about the structure of the themes directory, but the basic framework is good and I should be able to make things work by making our current them object conform to Themer::Base’s interface and duck type my way to the sunny uplands of Edge Rails compatibility.
Which will be nice.
I like the themer approach a lot. Instead of monkeying about in the guts of rails, it monkeys about in front of Rails. It overrides render so that you can pass it a theme/lookup object. If it sees a lookup object, it uses that to rewrite the rest of the render arguments into a form that will render the right thing using the standard implementation of render. In a work project I’ve taken a similar approach to handling polymorphic routes for things like:
map.resources :pictures do |pics|
pics.resources.comments
end
map.resources :users do |users|
users.resources.comments
endI ended up with a to_params method defined on my Comment model, and stuck an extended url_for in front of the default Rails version, which looks something like:
def url_for_with_to_params(*arguments)
if arguments[0].respond_to?(:to_params)
with_options(arguments.shift.to_params) do |mapper|
mapper.url_for_without_to_params(*arguments)
end
else
url_for_without_to_params(*arguments)
end
end
alias_method_chain :url_for, :to_paramsWhich is so much neater than the last time I attacked this particular problem (see the acts_as_resource plugin).
One of the nice things about Rails is that, although it’s opinionated and somewhat liberal with the syntactic vinegar for things the core team don’t think is the Right Way, they’re pretty good at leaving the door open for people like me who have other opinions. Both the themer plugin and my as yet unpluginized extension of url_for work by using existing capabilities in new ways and, because those capabilities are documented we can expect them to continue to work over multiple versions of Rails. Plugins that achieve similar effects by monkeying with Rails’s internal interfaces are hostages to fortune. Internal interfaces are free to change at any time, even between point releases, so a plugin can be left high and dry with surprising rapidity. Just ask the Rails Engines folk.
Hello Berlin!
Well… that was a fun flight. We’ve missed the Bratwurst on Rails event that the Berlin Ruby folks were putting on, so it’s a simple matter of getting some sleep before heading over to the conference hotel at ungodly o’clock to register in time for the first of the Railsconf tutorials.
If anyone knows of a good professional photolab in Berlin that can do black and white film dev + scan overnight, I’d be very interested to hear about it. I’ve managed to cover the last couple of O’Reilly European conferences in a timely fashion without having to go digital and I don’t want to break that record.
A tiny ruby niggle 32
You know what? I’m starting to miss compulsory semicolons as statement terminators in Ruby.
“What?” I hear you say. “But not needing semicolons is one of Ruby’s cardinal virtues! Are you mad?”
I don’t think so, but maybe you’ll disagree after I explain further.
Here’s a piece of code that I might write if semicolons were the only way of terminating a statement:
Category.should_receive(:find_by_permalink)
.with('foo')
.and_return(mock_category);Or how about a complex find query
def find_tags_for(tag_maker, order = 'count')
klass = tag_maker.class
find :all
, :select => 'tags.*, count(tags.id) count'
, :group => Tag.sql_grouping
, :joins =>
"LEFT JOIN taggings ON "
+ " tags.id = taggings.tag_id "
+ "LEFT JOIN bookmarks ON "
+ " bookmarks.id = taggings.taggable_id "
+ " AND taggings.taggable_type = 'Bookmark' "
+ "LEFT JOIN #{klass.table_name} ON "
+ " #{klass.table_name}.id = bookmarks.#{klass.to_s.underscore}_id"
, :conditions => conditions_for(tag_holder)
, :order => (order == 'count')
? 'count(tags.id) desc, tags.name'
: "tags.name"
, :readonly => true
;
endI first came across the idea of the leading comma in Damian Conway’s excellent Perl Best Practices. The idea is that, by leading with the comma it’s very easy to add a new argument to an argument list or hash specification without having to remember to stick a comma on the end of the preceding line if it was at the end, and also, the leading comma makes it very plain that the line is a continuation of its predecessor in some way.
To make the examples work in Ruby, you have to add a \ to the end of each line that has a continuation, so the first example has to be written:
Category.should_receive(:find_by_permalink) \
.with('foo') \
.and_return(mock_category);Lining up the \s helps to stop them disappearing, but it’s an awful faff.
What tends to happen (in the rails source especially) is that ruby programmers simply don’t break their lines up. A quick search of the rails source finds plenty of lines more than 160 characters long.
Of course, some will argue that it doesn’t matter, that the old 80 column limit is a silly hangover from the days of steam when the only way to interact with your code was through an 80 column, green phosphor terminal. They have a point. An arbitrary line limit is silly, and we should get over it, especially in source code. However, unless you’re going to go around with every window open to its maximum width, lines will wrap, and they won’t do it nicely, or respect the indentation conventions of your language. Long lines are murder in diffs too, finding the point of difference is so much easier when your eye doesn’t have to scan an epic line.
It’s a shame there’s no way of forcing ruby’s parser to require semicolons as statement terminators for those programmers like me who think that the restriction that a statement must end with a semicolon is worth the freedom to break lines where we like without needing to escape every line break. It’s a shame too that popular tools like Textmate are so clumsy when it comes to dealing with line breaks. I would attempt to hold Emacs up as a paragon in this respect, but its Ruby mode tends to get a wee bit bemused once you start breaking lines, so that’s no good.
Domino theory
It’s amazing how far reaching seemingly simple language design decisions can be isn’t it? Just getting rid of the need to terminate statements with a semicolon has an enormous effect on they way code in ruby looks. I’m just not sure that they look better.
Maybe Smalltalk got it really right – they chose to use the most valuable syntactic character of all, the space, to denote sending a message. That freed up the . for use as a statement (sentence?) terminator. Then that freed up ; for use in one of Smalltalk’s most distinctive patterns – the cascade. Where a Rails programmer might write:
form_for(@comment) do |f|
f.input(:author)
f.input(:title)
f.input(:body)
endA Smalltalk programmer might eliminate the need for a temporary variable by doing:
Comment>>printOn: html
(html formFor: self)
input: #author;
input: #title;
input: #body.All those input: ... messages get sent to the result of html formFor: self. Once you get the hang of it, it’s a really sweet bit of syntax.
Incidentally, there’s been some discussion on the squeak mailing lists of a companion to the cascade, which would use a ;; as a sort of ‘pipe’. The idea is to be able to replace code like:
((self collect: [:each | each wordCount)
inject: 0 into: [:total :each| total + each])
printOn: aStream.with
self collect: [:each | wordCount]
;; inject: 0 into: [:total :each | total + each]
;; printOn: aStream.(NB: Please ignore what those code snippets do, because that’s gruesome. Concentrate on how they do it).
Nobody’s quite proposed going as far as Haskell does with its Monads, which can be thought of as a magical land where the meaning of the semicolon changes according to what sort of Monad you’re in. (In an IO monad for instance, the semicolon imposes an evaluation order. In some other monad, the semicolon could just as easily denote a backtracking point). Then again, there’s nothing to stop the dedicated Smalltalker implementing something Monadish – every Smalltalk class can specify how its methods should be compiled after all…
In conclusion…
I’m not sure I’ve got a real conclusion for all this. I’m mostly musing. However, I do think it’s useful to think carefully about restrictions and what they free us to do as programmers. Lispers will wax lyrical about the way that their language’s pared down syntax lets them do amazing things with macros. Smalltalkers will defend to the death the idea that the only way to do anything is to send messages to objects. Pythonistas love their syntactic whitespace. Haskellers love their static typing (admittedly, they have an incredibly flexible notation for expressing type that leaves most other programming languages standing).
And any English speaker with ears will know that a poem like Dylan Thomas’s Do Not Go Gentle Into That Good Night gains much of its power from it’s form, the villanelle, one of the most restricted forms of poetry there is. Two lines repeating through the poem and a staggering number of rhymes to find:
Do not go gentle into that good night,
Old age should burn and rave at close of day;
Rage, rage against the dying of the light.
Though wise men at their end know dark is right,
Because their words had forked no lightning they
Do not go gentle into that good night.
Good men, the last wave by, crying how bright
Their frail deeds might have danced in a green bay,
Rage, rage against the dying of the light.
Wild men who caught and sang the sun in flight,
And learn, too late, they grieved it on its way,
Do not go gentle into that good night.
Grave men, near death, who see with blinding sight
Blind eyes could blaze like meteors and be gay,
Rage, rage against the dying of the light.
And you, my father, there on the sad height,
Curse, bless me now with your fierce tears, I pray.
Do not go gentle into that good night.
Rage, rage against the dying of the light.
If that’s not making a virtue of a restriction, I don’t know what is.

