Why Tabs Suck

Posted by Andrew on August 05, 2008

I’m quite often receive a puzzled look when I explain to .NET coders that, like Ruby developers and others, I prefer spaces (2 to be precise) over tabs. If you’re already a space aficionado you may go about your business, otherwise read on.

First of all, I don’t have a problem with the tab character per se. My problem is that it’s all too easy to misuse it. Observe:

This code, taken from an open source project that mandates tabs, illustrates the problem - The author has mistakenly applied a liberal sprinkling of spaces in with the tabs:

Of course, the problem manifests itself because my indent level is different to that of the author. And, to be honest, I don’t think I’ve ever seen a tab-indented project that didn’t suffer from this problem.

Spaces, on the other hand, are atomic and consistent - They always render the same way.

So which indent level? have shown that 2 to 4 is the sweet spot:

Although blocking style made no difference, the level of indentation had a significant effect on program comprehension. (2-4 spaces had the highest mean score for program comprehension.) We recommend that a moderate level of indentation be used to increase program comprehension and user satisfaction.

Personally, I prefer 2 spaces because it’s no less readable but uses less horizontal real estate.

Elegant Invariant Checking with C# 3

Posted by Andrew on July 30, 2008

Of all the great advice in , one of the ideas I’ve found most useful is that of . Most commonly, I check method preconditions using something like:

private void MyMethod(object arg1, string arg2)
  Invariant.ArgumentNotNull(arg1, "arg1"); // throws ArgumentNullException
  Invariant.ArgumentNotEmpty(arg2, "arg2"); // throws ArgumentOutOfRangeException
  // do stuff

I quite often check invariants at other points in a method too:

private void MyMethod(object arg1, string arg2)
  var myVar = AnotherMethod();
  Invariant.IsNotNull(myVar); // throws InvalidOperationException
  // do stuff with myVar

This approach works well but, in the case of preconditions, having to duplicate the argument name as a string is obviously not ideal. Perhaps using some of the new features of C# 3 we can do better?

Here’s one API I’ve been playing with:

private void MyMethod(object arg1, string arg2)
  Check.Argument(() => arg1.IsNotNull); // throws ArgumentNullException
  Check.Argument(() => arg2.IsNotEmpty); // throws ArgumentOutOfRangeException
  // do stuff

And for simple invariants:

private void MyMethod(object arg1, string arg2)
  var myVar = AnotherMethod();
  Check.Invariant(() => myVar.IsNotNull); // throws InvalidOperationException
  // do stuff with myVar

This approach leverages expression trees and extension methods to create a more fluent API and allows us to do away with the string argument when checking arguments.

Although I’m not 100% happy with it, I think I prefer this API. What do you think?

Download the code here.

NHaml News

Posted by Andrew on July 29, 2008

A while back we moved the NHaml core templating engine out of the MVCContrib project. This was done so that the core stuff could be maintained separately and to declutter the contrib project.

NHaml now lives on Google Code .

As part of the move, I’ve added a small, stand-alone ASP.NET MVC View Engine that doesn’t require MVCContrib - useful for people not wanting a dependency on contrib.

Other changes since the move are:

- Added NHaml configuration support into the core - was previously in the view engine.
- Improved view activation performance using LCG.
- Rendered view output is now written to a provided TextWriter improving perf for view engines.
- Incorporated a simple view engine framework into core.



Redmine - Trac without the Suck

Posted by Andrew on July 17, 2008

Looking for a free-as-in-beer issue tracker, forum, and generally flexible project management web application? If so, you could do a lot worse than checking out . We’ve been using it for a few days at work and I have to say it might be the nicest issue tracking system I’ve ever used.

Here’s the high-level feature list:

  • Multiple projects support
  • Flexible role based access control
  • Flexible issue tracking system
  • Gantt chart and calendar
  • News, documents & files management
  • Feeds & email notifications
  • Per project wiki
  • Per project forums
  • Simple time tracking functionality
  • Custom fields for issues, projects and users
  • SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs)
  • Multiple LDAP authentication support
  • User self-registration support
  • Multilanguage support
  • Multiple databases support

Out of the box it works just great, but it’s also extensible and modular and thus easy to customize to your particular requirements. It’s Rails-based too, so diving into the source is pretty easy. We’ve customized how it receives emails and themed it up a little.

Kudos and thanks to the Redmine team for a great piece of software!

When Memes Attack

Posted by Andrew on July 11, 2008

Seems like I’ve been . I shall use that as an excuse to be twice as terse!

How old were you when you started programming?


How did you get started in programming?

I needed a career and Computer Science had to be more interesting than Econ 101 *shudder* - Conveniently, I actually enjoyed it.

What was your first language?

Turbo Pascal and C++ at university. PowerBuilder commercially - long live the Data Window!

What was the first real program you wrote?

Something at ‘varsity. Maybe a DFA/NFA Regex thingie.

What languages have you used since you started programming?

Turbo Pascal, C, C++, PowerBuilder, Java, PL/SQL, VB/Script, JavaScript, Ruby, C#, Haskell.

What was your first professional programming gig?

Working on a land information system at the New Zealand Department for Courts.

If you knew then what you know now, would you have started programming?


If there is one thing you learned along the way that you would tell new developers, what would it be?

Find what you’re passionate about and do that.

What’s the most fun you’ve ever had… programming?

Whenever I can solve a challenging problem. A Haskell term unification program springs to mind. Along with the LightSpeed query engine and NHaml - variety is the key and constantly challenging yourself.

Over to: