28 March 2009

Command Line Options

A short introduction to CLOPS, a Java library for parsing the command line.

Did you ever write public static void main(String[] args)? If so, did you ever use args later? If yes and yes then you need CLOPS.

I can hear you saying that "handling args is very easy and doesn't justify learning a new technology." You are right that the benefits of a technology have to be weighted against its costs, and one of the most important costs that a technology incurs is the time spent learning it. Obviously, this poses a problem: How can you balance benefits and costs before learning? To solve this dilemma, it seems to me, most people rely on the assessment of others. So hear my word: Learning CLOPS is much easier than you think! Alas, I'm biased because I contributed to the design. I understand if you don't believe me: I started to contribute late precisely because in the beginning I was a skeptic myself. I had to see something working before changing my mind.

Most technologies have a complexity threshold: Products more complex than the threshold benefit from using the technology; products less complex than the threshold are hurt. HTML is a technology. Is it worth learning HTML for writing a blog? Not really. But is it worth learning if you want to develop a serious web-site? Probably. ViM is another technology. Is it worth learning for writing email? Definitely not. Is it worth learning for writing C programs? Maybe.

So what's the complexity threshold of CLOPS? A simple way to assess the complexity threshold of a technology is to pick a task and complete it with and without the technology. Let's write a program that prints "Hello world!" when run with no arguments, prints "Goodbye cruel world!" when run with the argument -bye, and prints a usage message in all other cases.

public class Main {
  public static void main(String[] args) {
    if (args.length > 1 || (args.length == 1 && !args[0].equals("-bye"))) {
      System.out.println("Usage: hello [-bye]");
      return;
    }
    if (args.length == 1)
      System.out.println("Goodbye cruel world!");
    else
      System.out.println("Hello world!");
  }
}

The CLOPS version is almost the same length:

public class Main {
  public static void main(String[] args) {
    HelloParser parser = new HelloParser();
    if (!parser.parse(args)) {
      System.out.println("Usage: hello [-bye]");
      return;
    }
    if (parser.getOptionStore().isByeSet())
      System.out.println("Goodbye cruel world!");
    else
      System.out.println("Hello world!");
  }
}

That's not too bad. But we do have to write one more file, let's call it hello.clo, that describes the command line.

NAME:: Hello
ARGS:: Bye: {"-bye"}
FORMAT:: Bye?;

To compile we must say

clops hello.clo
javac -cp clops-runtime.jar:. *.java

and to run we say

java -cp clops-runtime.jar:. Main

This is definitely more complicated than not using CLOPS. It indicates that for such a simple example it is not worth using CLOPS. But, by the same argument, for this example it is not worth using the build system ANT. Why write a build.xml file when you can get away without? Yet, for some strange reason some people keep using ANT even for such small projects. (Not me.) I believe the reason they are using it is that they get into a routine: copy the build.xml file of an old project, modify a little inside, and then operate in a familiar environment. It makes sense. Even if later the build process becomes more complicated than just invoking the Java compiler, it still is the case that a build can be achieved by one command: ant. The price, copying and editing slightly a file in the beginning, is something most developers are willing to pay.

It's the same with CLOPS. As soon as the command line starts to get a little more complicated you begin to feel the benefits. Are there two boolean options that shouldn't be given at the same time? You add one line to hello.clo: Your program and your documentation are updated. Does an option represent a file name that must exist? You add one keyword in hello.clo: Your program and your documentation are updated. Can an option appear only after another certain option? You guessed: You modify hello.clo slightly and you are done.

OK, now that you are convinced that it's worth using CLOPS when you write a command line tool it is time to address another question: Why would you write a command line tool in Java as opposed to, say, C? (If you are still not convinced that you should try CLOPS, then please pretend that you are for the next 5 minutes.) Well, why not? There are many programs that contain command line tools and are written in Java, such as web service testers, 3D graphics tools, bug finders, messenging and communication tools, testing frameworks, backup tools, and data reporting tools. It is true that at the moment most command line tools are written in C, but this will change. Of course, we'd be happy to see a C port of CLOPS.

We'd also be happy to hear what you think.

No comments:

Post a Comment

Note: (1) You need to have third-party cookies enabled in order to comment on Blogger. (2) Better to copy your comment before hitting publish/preview. Blogger sometimes eats comments on the first try, but the second works. Crazy Blogger.