Archive for December, 2006

Building Ruby 1.8.4, Rails 1.1.6, MySQL 5.0 on Tiger

Sunday, December 31st, 2006

FedEx deposited a MacBook Pro at my doorstep today. One of the first orders of business was getting a Rails development stack installed. Following Dan Benjamin’s instructions, (with the exception of installing the mongrel gem instead of building lighttpd), the process, including a test project to prove it all works, took 2 hours. Half of that time was spent downloading developer tools from Apple (to get the latest version of Xcode).

Given that Dan’s instructions are now over a year old, I’m very impressed with how well they’ve held up.

The latest advice is to install Ruby from MacPorts. I built Ruby from source instead, because I want the source to poke around in. At least that’s the excuse I’m sticking with.

While building the MySQL driver for Ruby, I had one brief scare in the form of two compile errors, but they seemed benign. My test project connected to MySql without any trouble.

Electricity sends a message

Tuesday, December 26th, 2006

Electricity is trying to tell me something today, and it’s been sending spooky messages.

My wife and I had dinner tonight at a local sushi restaurant. One with moving boats that you pick trays of sushi off of.

We’d been sitting at one corner of the bar for about 20 minutes when the lights flickered and went out. The place went quiet. Ten seconds later the power came back. There were some twitters and chuckles.

A minute later the power went out again. Someone started humming a Christmas song. More chuckling. The power came back on a few seconds later, and the chefs cheered something in Japanese.

A few minutes later the power went out a third time. More chuckling. But this time the lights stayed off, except for an emergency light over the door. One of the waiters got a flashlight. Without pumps to keep the water moving, the boats began slowing down. An occassional nudge kept them moving. The sushi chefs made a few orders by flashlight. After half an hour the emergency light failed. We paid our bill by flashlight (with exact change; the register was dead) and headed off.

Later, while catching up on email, I got a pop-up message from Dell Tech Support, suggesting that I recheck my laptop battery against their on-line recall list. I’d entered the battery’s serial number into the online checker twice over the last year, and had been told both times that the battery was good. But if they’re going to keep warning me, I’m going to keep checking. And the third time was the charm: the battery is now flagged as needing a free replacement. (I suspect Dell is quietly widening their recall as more videos of burning laptops show up on YouTube, and more Sony batteries are found to be faulty.)

In an apologetic followup email that arrived minutes later, Dell suggested (directed, really) removing the battery until the replacement arrives. No problem. I’d rather not chance having a Lithium-fueled fire on my desk.

While I was reading the email from Dell, my wife called out, asking me to come downstairs right away. On the way down I started picking up a faint “something electrical is starting to burn” smell–the smell that says “find the source and turn it off NOW.” As near as we could tell from sniffing around, the smell was from the Christmas tree lights, which are now unplugged and awaiting disposal. The “near as we can tell” part is unsettling, but the smell dissapated, and we’ve been unable to pin it down. It was definitely electrical.

Signs that you’re slipping into Design Debt

Monday, December 4th, 2006

Design Debt is one of the types of Technical Debt that you can work your way into gradually, usually without noticing. You might be keeping up with refactoring at the micro level, but at the macro level things have slowly gotten complex to the point of putting the brakes on momentum.

Recognizing gradual technical debt is made complicated by personal biases. As much as I trust my own instincts, I’m wary of firing off warning flares based soley on gut feel. It’s always possible that I’m the only one who is confused by some part of the system.

To reduce the effect of bias, I watch for the certain signs involving others on the team. Here are a few of them:

Estimation Spread. During iteration planning, when a team is estimating stories, a wide spread in estimates around a particular type of story might indicate that there’s lurking design debt. If the spread persists after you’ve discussd the estimates and the assumptions behind them in greater detail, you have a weak indicator of design debt. If a few people admit to being scared to take on the story because it means treading into code they don’t understand, you have a strong indicator.

Jockeying for Stories. If you’re on a team were any one (or any pair) should be able to pick up any story card, but you notice that there’s some gaming happening around a certain stories, such as the team manuevering it towards someone specific (e.g., the original authors of some area of code), you likely might some design debt in the form of specific knowledge in that persons’s head that hasn’t yet been converted into understandable code. The story may need to go to them now, but pair them up with someone who knows the code the least, and charge them with making sure that the resulting code is clear to both of them.

Depending on a Drawing. When you notice that others on your team have to refer to a diagram of some sort while working in an area of code, particularly when they are having to sketch out the diagram several times to get it comprehensible, that’s a good sign that design debt has built up. At the very least, save one of the drawings so that you don’t burn up time recreating it later. Comparing different verisons of the picture might also help point out what’s confusing (or just plain wrong) about the design.

Puzzling Tests. You’re progressing along steadily when a test a step or two removed from the action breaks unexpectedly. If you have to spend significant time puzzling through “what, exactly, is that test testing?” and other people on the team aren’t able to help, you’ve stumbled across test design debt. Test design debt can be nasty. Nobody really wants to spend time reworking an unrelated test, but disabling or deleting a test risks leaving a gap in test coverage. When this happens repeatedly in some area of test code, you have design debt to consider paying down. To avoid test design debt, take the time now to make sure that your tests are appropriately named, and either self-evident or well commented. Checking in a vague test is an invitation to trouble later.

As you notice signs of design debt, gradual or otherwise, take notes so that you have data that patterns might emerge from. At the very least, your notes will be good fodder for your next planning meeting or retrospective.

Spreading out Design

Monday, December 4th, 2006

Even before my first experience with full-on eXtreme Programming (XP), I was mulling the problem of how much design to do when. I’ve seen too many waterfallish projects either throw away much of their early design work, or go chaotic late in the schedule trying to cling to an early design in the face of a new reality that needs something different. When defending waterfall, it’s almost cliche to trot out some variation on Eisenhower’s famous saying, “In preparing for battle I have always found that plans are useless, but planning is indispensable.” I used to nod sagely, but now I see it as a poor excuse for the amount of waste that happens when you try to do the bulk of your design work up front.

XP seems to cure waste by spreading out design over the course of the project, doing only enough to satisfy the work at hand, followed by aggressive refactoring. Working on an XP project, I found, to my pleasant surprise, that this “small steps” approach worked very, very well. Doing small bursts of design, writing tests first, coding up the simplest implementation that would satisfy those tests, and then stopping to clean house by refactoring, proved to be an highly effective way to develop. Except when it didn’t.

Working a story (use case) at a time keeps us focused. Having a large body of tests gives us confidence that we aren’t screwing something else up (and nudges us towards writing testable code). Pairing helps spread domain and technical knowledge around. Refactoring keeps the code base clean. But this isn’t always enough to prevent design debt from building up.

There are points in the evolution of some systems where something happens that changes the game. It may be the introduction of a new requirement, such as “now make it work on the web”, “support simultaneous edits”, or “accept foreign currency”. Or it may happen when increased demand forces our system to expand beyond a single server. However it happens, the game has changed in some fundamental way, and the code base we have, or some significant part of it, isn’t structured in way that fully supports the direction we now find ourselves headed. We could try continuing to move ahead in small steps, but some of those steps get harder and harder to take. It’s time to invest a larger chunk of time in design, with the intent of getting ourselves back on the “small incremental design” track.

So plan to spread out your design, but don’t expect to spread it smoothly like peanut butter. Expect some big chunks.

On a slightly related note, this video interview with Ron Jeffries is excellent. It’s mostly about dealing with fixed dates and the importance of testing, but he makes some points about spreading out design, and not expecting it to spread evenly, that might be helpful if you find yourself in setting expectations about using Agile.