Stay Beautiful

Mr Hansson has been winding people up recently, with his Twitter Controversy. But one of his more polite recent posts is about Seaside - a Smalltalk web framework that uses stateful objects on the server to allow a modal-style flow of control within your web application. One component receives a callback as the user clicks a link, it calls into another component and sits and waits until the second component returns control to the first - just like calling a subroutine.

I’ve made no secret of my love of Smalltalk - it’s what attracted me to Ruby and Rails in the first place. There’s a beauty about Smalltalk code (although please forgive any typos in the code below as I’ve not done any for a while) that you rarely see anywhere else, although Rails has it in places. I could go on for hours about:

  under21s:= people collect: [ person | person under21 ].  

Is that better than:

  under_21s = people.collect do | person |     person.under_21?   end

Not much in it. Ruby has the question mark - I like that as it makes the code read better. But Smalltalk has less superflous punctuation to make it read better still. And I love the full-stop to finish the sentence.

How about:

  nail needsHitting ifTrue: [ nail hitOn: #TheHead with: aHammer ].

Versus:

  nail.hit(:on => :the_head, :with => hammer) if nail.needs_hitting?

Ruby has the if at the end of the sentence, which I really like - and it’s even better when using unless. And Smalltalk has its slightly weird “everything is an object or message” ifTrue: method on the true and false instance variables that lead to something that is a bit less readable than the Ruby. But Smalltalk doesn’t need the parenthesis. And blocks are passed as normal objects (not weird add-ons that may or may not be tacked on to the end and sometimes implicitly converted to Procs). And if is not a reserved word.

Recently I’ve noticed the Smalltalk creeping into my Ruby style. Things like:

  validate(course, :against => template, :on => this_date)

Which is reasonable. But the brackets just kill me.

And then I had to write this:

  form_for(:course_template,     :url => course_template_path(@course_template),     :html => {:method => :put} do | form |     # form.stuff  end

It’s awful (yeah, yeah, I need SimplyHelpful).

What about, in config/routes.rb:

  map.resources(:course_templates,     :member => {:build_courses => :get, :do_build_courses => :post}) do | course_template |    course_template.resources(:course_details)  end

They really ought to read:

  courseTemplates:= map resourcesCalled: #CourseTemplates;    withAnAdditional: #GetMethod :called #BuildCourses :on #Members;    withAnAdditional: #PostMethod :called #DoBuildCourses :on #Members;    nesting: (map resourcesCalled: #CourseDetails).

Note: the nested call to resourcesCalled is actually sent to map, not to a nested object as in the Ruby original.

A literal translation would be:

  map.resources_called(:course_templates).with_an_additional(    :get_method, :called => :build_courses, :on => :members).with_an_additional(    :post_method, :called => :do_build_courses, :on => :members).nesting(      map.resources_called(:course_details)    )

The semi-colon chains method calls together (assuming each call returns the original return value from map.resources_called. But it’s really really ugly in Ruby.

The closest I can think of for this is:

  map.resources_called(:course_templates,     :adding => [      GetMethod.called(:build_courses, :on => :members),       PostMethod.called(:do_build_courses, :on => :members)    ],     :nesting => map.resources_called(:course_details)  )

which is a lot better but still pretty ugly (nested brackets - urgh).

Of course, map.resources is probably an instance of DHH’s syntactic vinegar - I’m sure that in his mind you should never add extra calls as it breaks the nice clean REST architecture. Well tough. I think myserver.com/course_templates/23;build_courses describes what I want very succinctly.

It’s definitely something that’s on my radar now … I want my Ruby and Rails code to be beautiful. Otherwise I may just be looking at Seaside in more depth.

This entry was posted on Tuesday, April 17th, 2007 at 7:34 pm and is filed under Beautiful Code, Ruby on Rails and Software Development. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply