Just A Summary

Piers Cawley Practices Punditry

Typo on Rails 2 1

Posted by Piers Cawley Fri, 05 Oct 2007 20:09:04 GMT

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

Posted by Piers Cawley Sun, 30 Sep 2007 07:56:22 GMT

James Duncan Davidson

James Duncan Davidson

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

Posted by Piers Cawley Thu, 27 Sep 2007 23:30:29 GMT

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

Posted by Piers Cawley Wed, 26 Sep 2007 10:51:24 GMT

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

Posted by Piers Cawley Sun, 23 Sep 2007 19:09:24 GMT

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
end

I 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_params

Which 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!

Posted by Piers Cawley Sun, 16 Sep 2007 19:58:48 GMT

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

Posted by Piers Cawley Sun, 09 Sep 2007 07:51:00 GMT

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
    ;
end

I 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)
end

A 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.

Flash and Javascript, sitting in a tree... 7

Posted by Piers Cawley Fri, 31 Aug 2007 11:44:44 GMT

We’re looking for somebody who can make Flash 8 and javascript play well together on IE 6/7, Firefox and Safari. If you fit the bill, please drop me a line at pdcawley@bofh.org.uk with a pointer or two to examples of your skills and you, me and my boss will have a nice little talk.

We need a flash application which can be controlled via Javascript – we really don’t want to go sticking 10-15 tiny flash buttons on every page if we can help it, just so they can tell the main app (sitting in another window) that the user did something. We have an application that works with Flash 8 and above, but it only works reliably in Firefox. It breaks more or less horribly in IE 6 and 7 and is a wee bit flaky under Safari 2. I haven’t a clue how well it plays with Opera.

Now, on a personal site, I’d be reasonably happy to live with Firefox only and maybe Safari 2, but this isn’t a personal site, so that’s out of the window.

So, if you think you fit the bill, or you want to know a bit more about the problem, please drop me a line. Save me from having to learn ActionScript as well, when I barely know Javascript yet.

Typo stuff

Posted by Piers Cawley Fri, 31 Aug 2007 08:07:04 GMT

If you’ve been running on the Typo edge recently, you’ll be all too painfully aware that there have been issues with the cache being flushed at the wrong times and not flushed at all at others. Which is not a happy state of affairs.

However, I’ve recently got back to working on Typo and, after a few warmup refactorings and some missteps, I think caching is working properly now.

There’s lots more work to do (there always is) but I reckon that you could do worse than bump your installation to r1513, which is what I’m running here.

Today's Noun Is: Notation 4

Posted by Piers Cawley Tue, 28 Aug 2007 21:20:00 GMT

Remember back when I wrote about metaprogramming and programming being the same thing?

Well, Libraries, Domain Specific Languages, Domain Agnostic Languages, Pidgins, YAML, .INI files and the like are all the same thing. They’re all notation.

That’s the thing to remember. Good notation makes life easy. Bad (or inappropriate) notation makes it hard (or, in some cases, fun). There’s no point striving to write a pidgin or DSL if your problem can be solved easily enough with a well factored set of loosely coupled classes. After all, even the neatest and cleanest of domain specific languages has to be learned. Meanwhile a class library that’s respects the language of your problem domain can be easier to learn because the notation with which the library is implemented is plain old YFL and your team already knows that (and if it doesn’t, you have bigger problems). Learning the class library is like learning about the problem domain and vice versa. Learning one supports learning the other.

I’m of the opinion that DSLs and pidgins are at their most when their domains are generic. So ActiveRecord’s most useful language like interfaces are related to general problems like expressing the relationships between objects or describing how to validate an object. Backus-Naur Form, Perl compatible regular expressions, parser combinators are all useful for solving the generic parsing and lexing problems that crop up everywhere. Data serialization notations like YAML, FASTA, XML, CSV, JSON and all the others are useful when you want a generic way to pass data between systems. All of these notations are narrow in their focus, but broad in the sense that the things that they focus on are ubiquitous.

The most useful notation for your specific task is almost always a well factored set of classes or functions (depends on your language of choice) which reflects the language of your problem domain. Different parts of your program might well make use of a wide range of ‘donor’ notations, but it’s a rare problem that’s going to require to you implement a full blown language in order to solve it.

Don’t worry about whether something’s a DSL, pidgin or a library. What it is is notation. A better question is is “does this notation help me solve my problem?”. If the answer is no, find better notation. Or keep plugging on with what you’ve got, but don’t fool yourself about your reasons for using the notation – not everyone’s here for the hunting after all.

Older posts: 1 2 3 4 5 6 ... 29



Just A Summary