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.