Coding guidelines

I've been looking at long lists of coding guidelines in other places, and it got me to thinking about my own rules of thumb for coding. I think of them as a list of short thoughts to get me in the right frame of mind to code.

You Never Code Alone

Always remember, even when you're the only person sat at the keyboard, that you are working as part of a team with those who will be maintaining the code. Treat them with respect and make their life easy. That means: don't assume they're fools and don't assume they don't know the programming language. Assume instead that they have roughly the same level of skill as you and hopefully a little more -- after all, the future maintainance programmer will probably be you. However, do assume that they don't have the entire state of the project in their heads like you do right now.

Don't Repeat Yourself

Naming is Really Important

Spending ten minutes now to come up with the right name for something will pay for itself in the future.

Work on one level at a time

In a particular method, concentrate on making the flow of the method as clear as possible. Push details into helper methods, don't worry if those methods are really short, worry instead that you're about three levels of braces deep already. Pushing something into a helper method gives you an opportunity to come up with a really good name, and that means you won't have to use a comment.

Comment only when absolutely necessary

If you find yourself seasoning a method with comments then stop and think for a minute. Try and find a way of expressing your intent more clearly in code. Save comments for answering 'why' questions; if your code can't answer the 'what' questions by itself then it probably needs more work.

Write the tests!

If you don't have a test for it, how do you know you're doing it right? This is specially important when you come to change how something is done. But don't forget that sometimes the tests are wrong.

Everything else being equal, return $self

And fail with an exception. I know, it looks like a makeweight. But every time I've ignored this guideline I've found myself regretting it later.

Fix it now!

If you come up with a better way of doing something that means changing a pile of other classes, then change the pile of other classes. Don't live with broken windows or you will regret it later. Don't leave long blocks of commented out code and other cruft lying around -- you have revision control for a reason

Decide later

Unless you absolutely have to decide now. But don't be afraid to change your mind

Solve today's problem

Don't worry about tomorrow. So what if, in three weeks time you have to redo some of what you did today, it's not like you're building a house.

Use a revision control system

CVS, Subversion, RCS, perforce, SCCS I don't care what you choose, but choose. Revision control is not an option.

Use your judgement

Consistency is good. Guidelines are good. But one of the measures of true skill is knowing when to ignore a guideline or dispense with consistency

09:06 AM

Phew...

Okay, I finished refactoring my transaction objects and I've got all the tests back running again (moving to using a state object actually made things a little stricter; it turns out some of the tests were playing fast and loose so I had to tweak one or two of them slightly (and fix a few bad assumptions in the state code of course)).

You really notice how useful tests are when you attempt something like this though. Every time I moved a method over to the state, I ran the tests and made sure everything was passing (modulo a couple of test scripts that I knew I'd have to leave failing until I'd completed the move).

Any failing tests pointed me back to areas where I'd misunderstood what was going on, and the whole thing gave me confidence that the cleaned up code was still doing the same thing as the old ugly code. I've inherited rats' nests like this before, and without tests it's a nightmare, you end up spending ages trying to capture the old behaviour with tests before you can go on to actually cleaning up the code.

Next step, unifying this state object with the 'dispatch state' that a transaction hangs onto as a sort of 'bookmark' into its processing pipeline.

Thursday November 21, 2002

07:10 AM

Real life and patterns

So, I have this funky transaction object, with all sorts of state dependent behaviour. There's loads of methods with a very similar nest of conditional logic at the top.

So, being a good boy, I add a 'state' attribute to my class and start moving things over to my State classes. I move the first couple of methods over, run the tests and a huge pile of 'em fail. Big style.

So, I look through the code and find a repeated:

croak "some message" unless $self->{foo}{bar};

and the tests are failing 'cos they're dying with that self same message. So, we 'Extract Method' on that $self->{foo}{bar} into a is_initialized method, rewrite is_initialized to do $self->state->is_initialized, and Robert is our parent's sibling.

Of course, this refactoring would have been so much easier if we already had an Cis_initialized method. Just goes to show that, no matter how small the unit of repetition is, the DRY Principle applies. It also goes some way to showing that there's something in Design Patterns, but that's an argument for another day...

Oh dear...

Quake Rocks Britain

Was the headline on one of the newspapers as I came into London. I confess that I found myself wondering if iD had made a surprise software release that was proving very popular. But, rather boringly, it turns out there was an earthquake in Birmingham.

Thursday September 19, 2002

04:54 AM

Digital Schmigital. (or, why my parents are stars)

Once upon a time I had a Wista Technical Field Camera (contains Engrish), and a very fine piece of kit it was. However, having spent far too long 'between jobs', I had to sell it last year. And boy have I missed it.

The weird thing is, I never really took that many photos with it, you don't with a large format camera. But I can say that I was proud of every photo I did take with it. There's something about the slowness (and the costs per exposure come to that) of working with large format that makes you consider carefully and visualize all your shots. Plus, when your camera rig weighs as much as mine did, you tend to leave it in the car until you're sure of the shot you want.

After a year of wishing I still had the camera (I'd kept a 150mm lens, for old times' sake, but pretty much everything else got sold), and thinking that I'd probably have been better off selling my 35mm rig, I mentioned this to my parents. So, on my Birthday last Sunday I got a b'day card with the magic phrase 'IOU 1 camera' in it. I now have an Ebony 45S on order from Robert White and I'm so excited.

Weirdly, it's also got me thinking about the whole 35mm versus Digital thing. I still think real film is better than digital for 'considered' work, but you relinquish so much control with 35mm. One of the important tools of black and white photography and visualization is the 'Zone System', developed by Ansel Adams. To use the system to its best advantage you (potentially) need to develop each negative differently; with 35mm, unless you make every exposure in the same lighting conditions, you really can't do that. For me, this pretty much pushes 35mm towards being used for 'record' work and informal portraiture, which is where the immediacy of digital really shines through.

So, time to start saving the pennies for a D100 and the very lovely 17-35/2.8 AFS lens that Nikon do. I think I've just had a passion reignited.

Wednesday September 18, 2002

04:56 PM

Coo... have we done all that?

James asked me to check out the slides for his Pixie presentation at YAPC, which he'll be giving tomorrow. Pixie is the Object Persistence tool that James, Leon and I have been working on for the past few months. (Although I think I've written the bulk of the code, because I've been the one who actually needs a working Pixie, the design has been very much a collaborative affair, and Pixie wouldn't have come about without James' original, very cunning idea about how to work out what needs storing.)

Now I've been aware as I've worked on it that it's doing some pretty cool stuff, but it's only when I read the presentation that I realised quite how cool it is already, and it's still got some way to go.

Right now, Pixie gives you:

Object persistence for virtually any object with a hash or array based representation. Without schemas

Object persistence for objects that use Regexp or simple scalar references, and don't hold any other 'out of band' information, but you have to do sub Class::px_is_storable { 1 }

Object persistence for any other kind of class you care to mention, provided those classes make use of Pixie's 'Complicity' features.

Automatic management of object locks, either exclusive, shared, or readonly, with unlocking handled correctly when an object goes out of scope.

Custom DESTROY behaviour for all objects managed by Pixie, without any reblessing, lexical hooks or whatever: If your objects already have DESTROY behaviour, that behaviour will be called transparently. I may be releasing a version of the code that does this, probably called 'Ref::Footnotes', but I'm not sure yet.

A test suite that uses characters from Buffy the Vampire Slayer (A small thing, but it is a product of London.pm members)

Yes, there are things it can't do: we don't have a query language (but, dammit, we don't want one, and if you do Pixie is subclassable); if your objects do tricks with weakrefs you'll probably have to make use of complicity; the documentation is currently lousy; the datastore isn't garbage collected (yet, that's what I'm working on at the moment, it's coming on nicely thanks) and the build process could use some work.

All in all, I think Pixie's a pretty impressive bit of software and, what's more, you can get a relatively recent version of it (released on Monday) from CPAN to play with. I commend it to you.

Wednesday August 28, 2002

03:25 AM

Whee!

As you may know, I've been writing Perl 6 summaries, which I've been posting to the mailing lists, and which O'Reilly have been publishing on the the perl.com website. The reason that they haven't been published here on use.perl.org is that ORA will pay for exclusive content.

My plan was that I'd get them to pay my fee for the summaries directly to The Perl Foundation and I'd get to give the summaries back to the community and make some money to support Larry at the same time.

However, this proved a little tricky as O'Reilly weren't set up to be able to make the payments directly to TPF, they'd have to pay me and then I'd donate the money. But having the money cross the pond twice, shedding bank fees and commission in both directions just seemed silly.

So, last night I got word from Gnat that ORA have sorted out what needs to be done and payments for the perl 6 summaries will start flowing to the Perl Foundation. Hurrah!

And, this morning, I find that Dave Cross has written a 'linkshortener' for me. Life is good.

Monday August 26, 2002

02:14 PM

Mmm...

I just got back from Towersey Folk Festival where I had a fantastic time catching up with old friends and standing in a converted barn in a pub's grounds singing my head off (with a certain amount of friendly competition for who could find the best harmony line.) Great stuff.

Oh yes, in the instrument sales tent there was a chap selling simple system wooden flutes, which are just gorgeous. And Gill's just bought me one for an early birthday present. I am chuffed stupid, it's been about 25 years since I had a flute (a metal boehm system job, very different from this thing, which has the same fingering as a penny whistle.) Time to start seriously practicing.