Coding by Convention

I’ve been meaning for a while to have a play around with Ruby on Rails, on the basis that anything generating so much hype over the last year or two deserves some level of investigation, if only to see whether the hype is justified. So, I spent a couple of days working through Agile Web Development with Rails and, well, it’s pretty nice. I can certainly appreciate a development environment that goes to such endearing effort to do work for you without getting in the way – a fairly tricky balancing act. I came to the book with a working knowledge of Ruby but zero practical exposure to Rails, and on top of that I’m not a web developer so could not bring much contextual experience to the table. Despite this, I worked through the book and ended up with a functional book-store application in about 15 hours. Not too shabby.

So how does Rails achieve such power and productivity? The answer is largely that Rails, more so than pretty much any other development environment I’ve used, leverages the power of convention. That is, if you stay ‘on rails’ and behave the way Rails wants you to, then in return you get a great deal of functionality for free. A kind of technological “you scratch my back, and I’ll scratch yours”. If you structure your application as Rails expects, then Rails will automatically hook everything up for you. If you name your database tables as Rails wants you to, and create the primary/foreign key id columns that Rails expects, then Rails will take care of all your object-relational-mapping needs for you. Sounds like a good deal, yes?

Rails doesn’t expect you to jump through all these hoops yourself though. It provides a number of useful scripts that you can use to perform the common tasks you want to do, in the way that Rails wants you to do them. Probably the best example of this is when you first start a new project. You ask Rails to create an application for you, with the name you specify, then off it goes – and creates 45 files in 37 directories, without you having to lift a finger.

$ rails dummy
      create
      create  app/controllers
      ...
      <snip>
      ...
      create  log/development.log
      create  log/test.log
$ find dummy/ -type f |wc -l
45
$ find dummy/ -type d |wc -l
37

Compare this to a newborn ASP.Net application created using the Web Site wizard in Visual Studio 2005:

$ find WebSite1/ -type f |wc -l
2
$ find WebSite1/ -type d |wc -l
2

A pretty substantial difference. And if you stay within the confines of Rails’ expectations when adding to the project – which is very easy to do since you are provided with more generators for creating models, controllers, and migrations (basically incremental DB deployment scripts) – then you end up with a nicely structured application in accordance with the hallowed principles of MVC design, and everything is glued together automatically. Create a new data model, and your controller is immediately able to load it from the database along with all its relational buddies in a nice aggregated object structure with just one line of code (as long as you remembered to add all the has_many and belongs_to calls, of course). Store that data object in a controller member variable, and your views can access it for display. Use one of the magical rake incantations and get a DB-backed session management system which will horizontally scale in a load-balanced environment. Run the script/console script and you are dropped into a fully interactive command-line environment similar to irb, where you can instantiate and interact with all your objects dynamically. Tail the development log and you can see all the generated SQL as it is executed, and even get indicated performance in terms of theoretical request-per-second capacity. It’s all just fab. Nothing spectacularly new, of course; each individual feature has been done before, but Rails pulls them all together very nicely indeed.

As I worked through the aforementioned book, however, it was very clear that without the guiding instruction of the esteemed Dave Thomas and DHH I’d be up the creek without a paddle, and that got me thinking. Programming by convention is all great and frictionless and wonderful as long as you know the conventions. Imagine, if you will, the sheer blank incomprehension of a maintenance programmer who’s never heard of Rails, sitting down to tweak a Rails application.

Wait, what? How can this happen? Surely everyone has heard of Rails by now? Nope, sorry, but the truth is that the majority of programmers are clock-punchers living in a single-language world who don’t read blogs, or play around with tech in their own time, and haven’t even heard of Linux, let alone Rails. Their single language will likely be an everyday static language like Java or C#, which will leave them ill-prepared for many of the dynamic tricks in idiomatic Ruby.

Ah, but surely the kind of forward-thinking proto-company that builds its product on RoR would never hire non-Ruby-savvy developers anyway? That might be the case if you drink the 37signals Kool-Aid and think that any RoR company is by default über-smart and infallible, but in the real world it doesn’t work like that; there are countless tiny non-technical companies out there with just one or two developers – I know, because I spent a few years working at one – and maybe their current developers are cool enough to use RoR, but when they inevitably leave and the tech-illiterate management hire a replacement, you can guarantee that the job spec will not include minor details like “must have at least heard of Ruby on Rails”.

So, our imaginary maintenance guy – let’s call him Ted – hired by a non-technical company to look after a web application, peers for the first time into the 37 directories (assuming no new ones have been added) and >45 files (since new ones will most certainly have been added), and nothing makes any sense. Even assuming Ted is smart enough to make reasonable guesses about Ruby syntax, and knows what MVC is, there’s no visible link between the different layers of the application. It isn’t clear how data is shuttled to and from the database. It isn’t clear why things don’t always work as expected when Ted tries to manually add new things, rather than using the Rails scripts (which he doesn’t know about), even when diligently trying to emulate the structure and layout of existing code. It all seems like sorcery. What is Ted to do?

The correct answer is to go and by a Rails book of course, or at least try and pick out the decent tutorials on the web (unfortunately, there’s a lot more chaff than wheat in this area, maybe a sign that Rails is becoming a bit more mainstream?). A few days of getting up-to-speed, and Ted achieves enlightenment and becomes mega-productive, and lives happily ever after. So coding by convention is a good thing, right?

Maybe.

I’m still uneasy about sorcery, and Rails is some of the most effective sorcery I’ve seen. The main problem is that, well, it’s sorcery. A couple of times in the 15 hours I spent going through Agile Web Development with Rails I hit problems. Not major ones, and always of my own making – some silly typo, or mistake coming from only having a working knowledge of Ruby rather than cosy familiarity. As is my wont, failure to spot the error after a cursory glance through the code led to a quick google search to see if I’ve hit a common problem, before resigning myself to going through the code in detail to sort it out (like all good programmers I’m a lazy devil).

On these periodic google jaunts I found lots and lots of forum posts and blog entries from people who, and let’s not mince words here, hadn’t the first clue what they were doing. People that had heard the Rails hype, bought the book (and probably the t-shirt), hit problems, and were now running around like a cargo cult expecting magic spells to solve all their problems. Restart WEBrick. rake db:sessions:clear. Roll the most recent migration back then forward again. None of these work? Sorry, can’t help. It reminds me of The IT Crowd’s “have you tried turning it off and on again?”.

I shouldn’t be harsh on these folks; at least they’re getting excited by Rails and are rolling up their sleeves and having a go, and no doubt some of them will succeed wildly and become far better, richer, more attractive programmers than I can ever hope to be. Also let me be clear that I think the productivity gains of software like Rails is a good thing, and Rails is certain to account for a good chunk of my tinkering time for the next few months. It worries me, however, when people try to run before they can walk, and the magic of coding by convention tends to encourage it.

I’ll leave it as an exercise for the reader to consider the implications of the fact that the sample application being conjured here by all these sorcerers’ apprentices is an e-commerce site, at a time when online fraud is skyrocketing.

I don’t mean to single out Ruby on Rails specifically, by the way, it’s just handy as an example due to its profile. Coding by convention is not new; if you want an older example of what happens when people are given programming tools that allow them to get something working – for fairly loose definitions of ‘working’ – without knowing much about what’s happening under the hood, then look at the atrocities committed with VB and databinding over the years.

Steve Yegge has a characteristically long and insightful rant on this subject, and is troubled by the difficulty of working out where to draw the line. The line, in this case, being the level of abstraction at which a programmer should understand a system – high enough not to be bogged down in insane detail (e.g. knowing how semiconductors work) but not so high that the role of programmer is reduced to that of sideshow conjurer, waving a cheap trick-shop wand and trusting to a higher power that everything will work out OK.

Maybe it’s just a generational disease. Maybe in ten years’ time all the apprentices who have graduated to fully-fledged sorcerers will be looking on in dismay at the young scamps creating Web 5.0 applications using Ruby on MagLev simply by burping commands into their Skype headsets, and writing cautionary blogs about the dangers of not knowing how to write a partial web template.

Theoretically, a perfect system – perhaps a descendant of Rails in the dim and distant future – would contain such exquisitely crafted assumptions and such frictionless conventions that it would never go wrong and always do the right thing. Thus, the need to understand anything at the lower level of abstraction required to sort out any problems is obviated, unless you are one of the very few Grand High Wizards who keep everything running smoothly. I don’t know whether it’s fortunate or unfortunate that such a system is unlikely to appear within my lifetime.

  • Share/Bookmark

Reindenting a File in Vim

I’m going to post a series of helpful Vim snippets here, particularly for features that I don’t necessarily use every day and hence forget about after a while. By posting them here, I’ve got a nice easy one-stop-shop for finding them.

The first tip is reindenting source code. Hitting ‘=‘ will reindent visually-selected code , or you can also use a motion to constrain the affected area. ‘gg=G‘ will reindent the entire file:

using System;

namespace IndentExample
{
public class Indent
{
public static void Main(string[] args)
{
Console.WriteLine("badgerbadgerbadger");
}
}
}

to

using System;

namespace IndentExample
{
    public class Indent
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("badgerbadgerbadger");
        }
    }
}

More info: http://www.vim.org/tips/tip.php?tip_id=83

  • Share/Bookmark

Renault Save the Queen

I don’t tend to go in for flag-waving patriotism a great deal. Whilst I think the armed forces deserve our respect and our thanks, I tend to find The Sun’s “Our Boys” rhetoric twee and jingoistic. Whilst I enjoy watching England play football (and anyone who’s watched them recently will know that’s not a statement to be taken lightly), the sound of Wembley stadium belting out God Save The Queen leaves me cold, and I can normally be found in the kitchen making a cuppa or opening another bottle of Bombardier during the last few minutes before kick-off.

So imagine my surprise when I finally got round to watching this week’s Top Gear last night and found myself with goosebumps at the end of Hammond’s F1 segment, where the Renault engineers hook the car up to a laptop and get the engine to belt out the national anthem.

So, what the hell has to be wrong with someone to be unmoved by 80,000 fans singing, but filled with national pride when a bloody car does it? The engine isn’t even English, it’s French!

  • Share/Bookmark

Technical Book Club

Back in October, personal finance blogger Trent at The Simple Dollar started an online book club for one of his favourite finance books. Good idea, I thought, so I’m nicking it. Starting in January, I’m running a technical book club at work with a few .Net devs, and I’ll write everything up and post it here, so if you’re so inclined you can follow along at home.

To start with, we’ll be reading language-agnostic books covering the fundamentals of software development in the real world, since it’s always valuable to refresh knowledge on the cornerstones of modern professional coding; later on this can diversify into specific technologies and subjects with more arcane, academic, or abstract overtones. Another benefit of starting with the basics is that we can concentrate on getting the format right without feeling overwhelmed by unfamiliar material.

So, the initial batch of texts will cover object-oriented design, design patterns, refactoring, code quality, and so on. Later, the idea is to study less immediate (but still vital) subjects like functional programming, compiler design, operating systems, etc.; and also to gain deeper knowledge of common specific technologies, e.g. the inner workings of the CLR or a JVM. I suspect people like stevey will argue that these latter subjects are more important than the others and should be done first, and they might even be right, but I’ve picked my approach and I’m sticking with it, so nuts to you stevey.

So, here’s the early schedule and probable books. The order we do these books might change – in fact the books themselves might change if, for example, we decide that Fowler’s Enterprise Patterns is more appropriate than the GoF’s Design Patterns. Each book will be agreed for certain in good time for it to be ordered and delivered before the scheduled start date, obviously.

Topic Book Start Date
OO Design
Object-Oriented Analysis and Design with Applications
14/01/2008
Design Patterns
Design Patterns: Elements of Reusable Object-Oriented Software
03/03/2008
Refactoring
Refactoring: Improving the Design of Existing Code
05/05/2008
Code Quality Pragmatic Programmer 07/07/2008
Legacy Code Working Effectively With Legacy Code 01/09/2008

In addition to these, we’ll also cover one chapter of Code Complete per week. So, there it is. If you want to tag along, get yourself a copy of Booch’s Object-Oriented Analysis and Design with Applications and McConnell’s seminal Code Complete, and tune in next month.

  • Share/Bookmark

Hello World

Woohoo, frist psot. This is my whole-sort-of-general-mishmash blog, in which I will be irregularly posting coding insights, recording handy bits of obscure info I want to be able to easily find in the future, writing the odd essay, musing on literature and mathematics (and occasionally considering how they are linked to programming), riffing on other blog posts, bemoaning the sorry state of the film industry, raving about how great films are, and generally whatever the hell else I feel like doing.

  • Share/Bookmark