In a way, Working Effectively with Legacy Code does what it says on the tin: gives advice on how to work with legacy code. But while the title is technically correct, it is also misleading enough to be harmful.

After all, I have been working with legacy code without any help, and making progress cleaning it up, too. So why would I need a book? What can it possibly do to help, other than commiserate and advise me to refactor? For a long time I dismissed the book as “probably won’t help me much in practice”.

Well, it turns out that the book is not really about how to work with legacy code. Michael Feathers has his own, very specific, definition of legacy code: for him it means code without tests. And he also has a very specific definition of working with legacy code: for him it means adding no more untested code. Whenever a change or a new feature is needed, the affected parts of the code base need to be made testable first.

Redefining the problem from “working with legacy code” to “making untestable code testable” suddenly makes the topic appear very useful indeed, and the book turned out to be excellent. Like numerous other reviewers, I wish I had read it a year ago!

It’s full of practical advice, with lots of great examples, rather than high-level principles. Very pragmatic, where other software design veer off into idealism: “you often need to make your design worse before you can make it better” was a recurring theme here that I really sympathise with. It was a very inspiring rbook, making my fingers itch to refactor. On top of that it’s interesting, well-written, and very obviously written by an experienced, knowledgeable expert.

The book is structured sort of like a cookbook, question-answer style: “I need to make a change. What methods should I test?” I cannot imagine using the book to look up answers to such specific, disjointed questions. No, the book needs to be read and digested, and then re-read and re-digested, repeating until you’ve fully internalized all its ideas. I’ve read it once from cover to cover (skipping only the C/C++ specific advice) and I know I will be browsing it for inspiration many times. The numerous cross-references make it a very browsable book.

However. I like the general idea of making all legacy code testable, but in practice it’s not always practicable. GUI code is the most obvious example: it’s hard to test in the best of cases, and in a legacy code base, making it testable is a hopeless battle. I’m not going to refactor an entire 1500-line aspx page so that I can test my one-line change which makes a certain element invisible in certain circumstances. And more generally, making legacy code “non-legacy” is a worthwhile goal, but sometimes the change really is small and safe enough, and entangled enough, that making it testable is just not worth it. But I guess the book needs to be more categorical than reality: aim for the stars, get to the treetops.

Amazon US, Amazon UK.

We have lots of scillas,

some scilla-like white flowers that the Internet says are puschkinia scilloides (porslinshyacint)

and the occasional yellow Star-of-Bethlehem (vårlök, kollane kuldtäht, gagea lutea).

Also a few violets, almost disappearing among the scillas

and some unidentified purple flowers.

There are daffodils coming, too, but they’re on the north side of the house and thus about a month late.

If you’re reading this blog in a web browser, you may have noticed a slight change to the looks. Banner images!

I’ve been thinking for a long while (about a year, since I first migrated to WordPress) that I would like to have a banner image or something of the sort, but never managed to settle on a design idea. I couldn’t think if any kind of photo that would fit. This Blog Needs No Name, because it has no mission, no message, no plan, and for the same reasons, it matches no image. (With the exception, perhaps, of an orange.)

But last week I finally found something. I have been reorganizing and tagging my old photos, and found some from the Chihuly exhibition I saw back in 2005. They’re beautiful and orange, and imply nothing more than that. (The whole installation looked like this.)

I discovered, in some weekend supplement or free newspaper or something, that Stieg Larsson was the world’s second best selling author last year. And I barely knew what books he had written – something in the crime genre, which I’m normally not at all interested in. But someone who sells that well is a phenomenon worth reading just for the sake of being informed, so I decided to read Stieg Larsson’s Millennium series.

One evening Eric came home with all three books and I got started. Read the first book in two days, during which I spent every free moment reading. Started on the second book straight after I finished #1, and then started #3 immediately after #2, and read until 2AM just so I wouldn’t have to wait until the morning to finish it.

You can easily find plot summaries for all three books on the web if you’re interested. To put it briefly, the books are about Michael Blomkvist (middle-aged crusading journalist full of righteous anger about economic crime etc) and Lisbeth Salander (punkish lone-wolf genius hacker girl) who solve mysteries and bring bad guys to justice.

Salander becomes more and more of a superhero, less and less believable. A socially inept loner suddenly impersonates a rich lady speaking German with a Norwegian accent? Digging herself out of a grave after being shot in the head? Come on…

The first book is a quiet, calm mystery story, where Michael tries to solve a decades-old missing person case (abandoned long ago by the police, but not by the people involved). The second book is more of a detective story, with police and motorcycle gangs – ups the pace and adds action and violence. The third book adds political conspiracy theories and turns into a semi-thriller.

So the series is a kind of spiral, escalating in speed and level of action, which was a bit of a disappointment for me. I got hooked by the first book, and wasn’t entirely happy about how the books shifted towards more action, more people and a larger scene. One of the redeeming qualities for the later books was that Lisbeth got more space, and she is more fun than Michael.

All three books are entertaining, full of suspense and memorable characters. The language is hard-boiled and the writing generally no-frills, with little effort wasted on scenery etc, as is standard for the genre. But it flows smoothly and has a lot of energy. Some reviewers complain about the pages wasted on diversions and off-topic ramblings, but in my opinion they add to the books’ charm. I liked the rough edges. Alltogether, lots of fun.

In Swedish: Män som hatar kvinnor, Flickan som lekte med elden, Luftslottet som sprängdes.

In English: The Girl with the Dragon Tattoo on Amazon UK, Amazon US; The Girl Who Played With Fire on Amazon UK, Amazon US; The Girl Who Kicked the Hornets’ Nest on Amazon UK, Amazon US.

Started learning RoR with the help of Rails for .NET Developers. Spent well over an hour just getting through the first two pages of creating my first app. After typing in the 3rd instruction as per the book, I got errors.

C:\dev> rails book_tracker
C:\dev> CD book_tracker
C:\dev> ruby script/generate scaffold book title:string author:string on_loan:boolean
  wrong constant name Title:stringController

Fine, I’ll google. Via Google the Ruby community tells me that I have an old version of Rails and need to upgrade – while Mac OS X comes with Ruby and Rails pre-installed, it’s not exactly the latest version.

I update Ruby and I update Rails and still I get the error. I uninstall and reinstall rails, confirm that I have the right version, reboot the computer, and still I get the error.

Back to Google. Perhaps I somehow still have the old version somewhere. I google for “multiple versions of rails” and find a brief blog post about Using Multiple Versions Of Rails that gives me this useful piece of information:

your individual rails projects store the version number they expect

Aha! I performed steps 1 and 2 of the tutorial before upgrading Rails, so step 3 was still hitting the old version rather than the new version. I delete the entire folder, redo steps 1 2 and 3 and bingo, it works.

Over an hour to perform a 5-minute task. Couldn’t rails -v report all versions of rails that I have, rather than just the topmost one in the list?

Another Open Spaces event today. This time it was officially not organized by the ALT.NET community because some of the people behind the ALT.NET movement have had a bit of a disagreement (“the movement is stagnating”, “don’t be so elitist”) about what ALT.NET is and should be. And since Scott Bellware, who’s on the “ALT.NET has degraded and we need a fresh start” side of the battle, joined our discussions, we were officially using his preferred name, which was “progressive software development”. In the discussions we kept slipping back to using ALT.NET since most of us, I think, never felt that we are part of any movement, and knew very little about the controversy. We just want to meet developers who think like we do and work with the same technologies, and really don’t care what they call it.

Today’s event was a bit different from the previous one. The presence of Scott Bellware (who’s not exactly a superstar in the developer world but still rather well-known in the .NET circles) changed the character and the focus of our discussions. Scott’s got a forceful personality (as revolutionaries and firebrands tend to) so some of the sessions veered from discussion into lecture. But they were good lectures, inspiring and interesting. A lot of talk about the meaning of quality, and what is needed to change the world of software development to focus more on quality and learning. I came home with a whole reading list about lean thinking and lean development, and a renewed desire to improve myself and my work. I’ve sort of relaxed for the last half-year and stagnated, not learned as much as I could. Time to pick up the pace again.

As a first step, I will make a new effort to learn Ruby. Why Ruby? Because the other thing I came home with was a book titled Rails for .NET Developers. Scott told us about a project he’s planning, which involves developing a Rails-based web site, and invited us to contribute. I liked his idea, but had to admit I would be of little use as a developer since I knew no Ruby. That’s no excuse! he said and offered me the book. What the heck, said I, took the book and decided to have a go. So not only have I met a celeb developer up close, I now also own a book that used to belong to a celeb developer, ha ha.

Thirty months, two and a half years. I know I keep saying that Ingrid is growing up, and of course it’s hardly news because that’s what all children do, but really I keep noticing how quickly she matures. The patterns of her movement, her facial expressions, all look more like those of an adult than those of a baby.

Life continues on a generally contented, positive path. No major upsets or mood swings. The only thing causing friction is boredom. It is becoming clearer all the time that Ingrid is a social creature, extroverted unlike both me and Eric, and loves to have people around her. She is happy at nursery, happy when we have guests or are visiting other people or at playgroup – and bored and clingy when it’s just the two of us at home.

When we spent the afternoon with Julia (her friend from nursery who lives across the street) and her sister, they played together with her toy kitchen and her balloons and the doll stroller, ran around, chased each other to the bedroom where they jumped up and down on the bed… full of energy.

On a normal weekday evening, on the other hand, Ingrid spends some time watching a movie, ideally with me keeping her company, then some time in the kitchen watching me prepare dinner or do the dishes, and then we read some. Perhaps we play a bit, together. She is totally not interested in playing with her toys on her own. For a while she enjoyed a computer game for small children, where she could make things happen by moving the mouse, but after a few weeks she lost interest, and the only thing she kept coming back to was a letter-matching game. She’s barely even interested in painting: several times now she’s told me she wants to paint, only to give up after a short while, and then spent more time washing up afterwards than she spent painting.

For doing “real” stuff is fun. Ingrid enjoyed planting bulbs and spreading fresh soil together with me. Now that it is warm outside, we go out to water the flowers, too. She’s getting good at pouring things: not just from the watering can (which doesn’t require much control, after all) but also pouring juice into her glass or cream into the saucepan. If the food is relatively solid, she’s sometimes served her own food, climbed down from the stepstool and carried her plate to the table, all on her own. With some guidance she can pour “one, two, three” measures of water into a pot, or a pinch of salt that I’ve poured onto her hand. And of course she can cut all sorts of bags and packaging, as well as herbs. Too bad all the veggies we eat tend to be crisp and crunchy and hard to cut, otherwise she could start practicing with a knife, too.

When we do play, our games tend to be small, random ones, things that we do on a whim, enjoy, and then occasionally come back to. Me pushing her over while she’s standing on the bed, which then evolves to her falling over when I barely poke her with a finger, and finally when I just point at her. Or word games: I say “ni ni ni… nina!” and she says “to to to… tool!” or “em em em… emme!”. Games with rules, where we are both supposed to do things a certain way, over and over again. But I’ve also noticed pretend play, when she picks up some invisible thing and tells me it’s peas or milk or some other thing I need to eat.

Rules are important. Rules are good, because it is easier for her to understand and accept a rule, than to accept daily negotiation. No shoes outside the hall. Teeth must be brushed every evening. Three small pieces or one large piece of candy in the afternoon when we get home, and then no more.

Speaking of candy, Ingrid has now learned to like ice cream, too. Until recently she’s enjoyed the taste but not the coldness. While we had to have rules about candy, we’ve never had to think about ice cream, because she just wasn’t interested. But now she takes tiny spoonfuls and actually eats them, and wants more. Other foods she likes just now: bell peppers, Kalles Kaviar (both long-time favourites), prunes, dates, peas, boiled eggs, bread dipped in soup.

She has learned about milk moustaches and found the concept so funny that she insists on drinking her yoghurt instead of eating it with a spoon, just so she can then show off her yoghurt moustache. Milk, by the way, becomes “coffee” when there is a spoon in the glass while she’s drinking from it.

Some practical stuff to finish this post off – less interesting to read now, but I think I will find this useful later on. Ingrid can now put on most clothes on her own, although trousers often end up backwards and shoes sometimes go on the wrong foot, and the sleeves on tight tops are difficult. On the other hand, she can manage gloves without any help at all.

Potty accidents still happen, but nowadays we almost always make it to the potty in time to catch the pee. With poo, unfortunately, making it to the potty is still the exception rather than the norm. But on the whole I have enough confidence in her potty skills to leave nappies off even when we’re going out on a longer trip, and just take the potty with us. (She doesn’t like big toilets.)

No change in sleeping habits since I reintroduced a fixed-ish bedtime. We start our evening routine around 8: brush the teeth, get a nappy on, choose a book, go to bed, maybe put the pyjamas on or maybe keep the t-shirt, read the book, fall asleep while I sit by the side of the bed. Asleep by 9, most days. Never wakes at night, now, but starts to get restless around 6 in the morning. At that point she sleepily rolls closer to me and puts a hand or a foot somewhere on my body, and goes back to sleep.

The code base I work with is in a pretty bad state. Much better than it was a year ago, but that’s still faint praise. At times I can avoid thinking about it, especially when we’re focusing on some new piece of functionality that is mostly independent of the legacy code. Other times I have to wade through all this old muck to get something done. That really makes me want to clean up, go in with a big broom and sweep all the dirt away. Whenever we’re ahead of schedule I take a day or so to focus on refactoring.

A day is a very short time to spend cleaning a big code base, so I want to make sure I spend it well. But the code is so messy that it’s hard to decide where to begin. It’s like when you have a house that hasn’t been cleaned for years: whichever part you start cleaning, something else grabs your attention because from another angle that looks even worse than the part you’re working on.

Do I start from the parts I need to touch most often?
From the most important parts?
From the dirtiest parts?
From the parts where I can get the most done in the shortest time?
From the riskiest, most complex parts?

Every time I face this decision I make a different choice, but in general I tend to pick the first of these strategies. The files I need to work with regularly get cleaner, but there are many places that I have never even looked at, and I’m sort of hoping that I never will, although I’m sure the day will come.

Saturday we took advantage of the great weather (warm and sunny enough for t-shirt and sandals) and went cycling in the morning. We cycled to Bögs gård, where I expected Ingrid to enjoy the animals. She couldn’t care less. But Eric and I got some sun and fresh air and exercise.

In the afternoon we worked on our hedge: Eric put in place the rest of the lawn edging, and we spread fertilizer and more soil around the bushes.

Sunday morning Ingrid and I went to our Estonian playgroup. She got to paint an egg during the crafts period. We spent Sunday afternoon and most of Monday in Uppsala with my mother and brother. Ingrid ate her painted egg, and more.

This afternoon we invited our neighbours over for afternoon play and dinner. Both their girls go to the same nursery as Ingrid, and the Julia, the younger one, is in the same group. They’ve been here at our place once before, and a few weeks ago Ingrid and I spent an afternoon at their house. Ingrid loved it, and she speaks almost every day about how she will soon be able to play with Julia again.

I’ve had a couple of really productive days. It feels like I’ve gotten more stuff done (the kind of discretionary should-do-at-some-point-but-not-just-now kind of stuff that keeps piling up on my todo list but that I rarely find time for) in the last few days than in the previous month. A half-day at work yesterday gave me 3 free hours, the spring sunshine has given me lots of energy, and Ingrid’s been unusually happy and unclingy today which gave me a chance to get stuff done in the garden.

  • Bought new socks and underwear
  • Bought a mouse and a display cable adapter for my Mac
  • Bought more towels for the bathroom
  • Ordered a new dishwasher
  • Took a trip to IKEA with Eric and Ingrid to buy a new kitchen cupboard
  • Bought a doll stroller for Ingrid
  • Filled in several of the mysterious burrow-like holes in the garden
  • Planted the bulbs I was going to plant in November