In the previous post, I showed the basic structure of a Getopt::Long-based CLI application. It’s simple and straightforward, but there are several repetitions that could be “normalized”.
First, the help message which often just contains program name, summary, usage line, and list of options. We could’ve generated this automatically had the specification contains enough metadata (Getopt::Long’s certainly isn’t because it only specifies list of option names and handlers).
The version message could also be generated.
(Actually Getopt::Long’s auto_help and auto_version can already do the above, although auto_help basically just extracts the help message from sections of the POD.)
Then we have the OPTIONS POD section, where I will also once again repeat listing the options along with the summary and description of each option.
So I find repeating myself three times for each option. And there are other repetitions involved, like repeating the abstract. These repetition is okay if I just write one or two programs, but I write hundreds. So after the tenth program or so I’m thinking that these repetitions are demoralizing. They’re tedious and feel like chore. And it’s annoying to often find yourself missing one or two places everytime you have to add/edit/remove an option. DRY (don’t repeat yourself) becomes one of my important principles when writing Perinci::CmdLine.
With tools like Dist::Zilla and even something like Getopt::Long::Descriptive, we can actually already remove these repetition. Since GL:Descriptive’s specification contains summaries as well as default values of each option, we can generate an automatic help message that is nicer. We can also write a Dist::Zilla plugin that takes this specification and generates the OPTIONS POD section from it.
But the idea behind Perinci::CmdLine is to take the DRY principle further. I’ve written tools and plugins to generate the whole POD/manpage (from abstract to the OPTIONS section as well as other sections) from the specification. And the specification goes beyond CLI application too, so I don’t have to repeat myself either when I’m outside the context of CLI. We will find out about these later. In the next post, we’ll discuss the basic structure of a Perinci::CmdLine-based CLI application.