A good excerise where metaprogramming may help is mixed GNU/POSIX-style option processing for command-line utilities. A descriptive explanation for this use-case is given here.
We want to simplify accessing option values as mush as possible. I suggest the actual work required to use options must be limited to 1) declaration of a simple JavaBean-style interface, and 2) acquiring a reference to that type using the very same array of string arguments that is passed to the main(String[] args) method; and we need not bother coding the interface implementation ourselves - it should be done implicitly.
A sample interface should look like this:
public interface ITestOptions
{
@Option(id = 0, required = true, opt = 'a', longOpt = "int-a", description = "a parameter", argumentTag = "valueOfA")
Integer getA();
@Option(id = 1, required = false, opt = 'b', longOpt = "int-b", description = "b parameter", argumentTag = "valueOfB")
Integer getB();
@Option(id = 2, required = false, opt = 'x', longOpt = "bool-x", description = "x parameter")
Boolean getX();
@Option(id = 3, required = false, opt = 'd', longOpt = "double-d", description = "d parameter", argumentTag = "amount")
Double getD();
@Option(id = 4, required = true, opt = 's', longOpt = "text-s", description = "s parameter", argumentTag = "brief")
String getS();
@Option(id = 5, required = false, opt = 'm', longOpt = "text-ms", description = "ms parameter", argumentTag = "patternList")
String[] getM();
@Option(id = 6, required = false, opt = 'z', description = "z parameter", argumentTag = "zet")
String[] getZ();
}
And here is how it is going to be used in our code:
final String[] args =
{ "-a", "12", "-b", "23", "-x", "-d", "3.14159", "-s", "a string", "-m", "\"alpha\",\"beta\",\"gamma\"" };
final ITestOptions cfg = ConfigUtils.parseCommandLine(args, ITestOptions.class);
assertEquals(12, cfg.getA());
assertEquals(23, cfg.getB());
assertEquals(3.14159, cfg.getD());
assertEquals("a string", cfg.getS());
assertEquals(true, cfg.getX());
assertArrayEquals(new String[] { "alpha", "beta", "gamma" }, cfg.getM());
Well, it is not at all that difficult as it seems.
I'll show this in the next few posts.
No comments:
Post a Comment