Sunday, August 19, 2007

Command line arguments considered global

I'm not gonna bother with introductions, yet. I'll see if I like this, and then I'll introduce myself.

On a software project I've recently become involved with, the others involved have this strange love of command line flags. They argue (rightly) that it speeds up their research cycle since they don't have to edit any files or compile before they start another run. This is research code, so keeping the experiment cycle to a minimum is their foremost concern. Alright, that make sense.

However, there's a larger problem: the unfettered use of command line arguments (and, more importantly, a global registry for these flags) gives all the same problems as global variables, and we all know how evil global variables are. Don't believe me? Here's a look at what some code looks like:

class Foo {
private BarFile bar;
public Foo() {
barfile = new BarFile(Args.getCLA("barfile"));
}
}
Ick. Ick. Ick. If you use these, don't write code like that, please. I'll love you forever. Try to allow people some kind of flexibility, or at least... document what flags you use. Prefer something like this:
class Foo {
private BarFile bar;
public Foo(){this(Args.getCLA("barfile"));}
public Foo(String pathToBarFile) {
barfile = new BarFile(Args.getCLA("barfile"));
}
}

That's not too bad, in fact that's down right reasonable. And you're probably saying, "that's not so bad. Just refactor!" Sure. But what if the ctor in question actually makes 3 member function calls before using the CLA. That's no fun to refactor, and it's confusing as hell to figure out where the configuration is coming from. Don't do this, or ninjas will kill kittens or Dijsktra or something.