dagolden/getopt-lucid — pull request #7 by thilp (2014-04-17 04:57:23+00:00)
Title: Automatic "usage" using a doc() modifier

Hello Sir,

I have often used this great module and I appreciate its clarity and efficiency. But today, after a lot of App::Cmd (and thus Getopt::Long::Descriptive), I missed the autogenerated "usage" text of G::L::Descriptive in G::Lucid. These "usages" are always the same boring thing to write; you already specified your options to G::Lucid and you don't want to write them again; and you forget to update that usage when you change G::Lucid's specifications, etc. I figured out that G::Lucid's design made it easy to add that feature, so here I am!

These four commits implement a `doc()` modifier on G::Lucid::Spec objects (to attach a description string to an option), build a "usage" text in G::Lucid objects from strings provided by doc() and attach this usage to G::Lucid::Exception::ARGV so that users can catch command-line errors this way (note the `$@->usage`):

```perl
if ($@) {
print "$@\n" && print $@->usage and exit 1
if ref $@ eq 'Getopt::Lucid::Exception::ARGV';
...
```
instead of:

```perl
if ($@) {
print "$@\n" && print_usage() && exit 1
if ref $@ eq 'Getopt::Lucid::Exception::ARGV';
...
```
where they need to write `print_usage` themselves.

Some things I'm not happy about in these commits:
- being forced to always pass `usage => $self->{usage}` in `throw_argv()`, but since `throw_argv()` isn't a G::Lucid method…
- no way to customize the autogenerated "usage" (I can't think of how I would like to customize it, though);
- this ugly `max` implementation in `_build_usage()` (but using `List::Util::max()` would mean adding an external dependency, since List::Util seems not to be in 5.6's core, and I believed it was not worth it for just a `max`);
- for a moment I tried to incorporate G::Lucid::Spec's `type` fields (_keypair_, _list_, etc.) in the "usage", but I ended up with overly long lines so I forgot that idea.

I hope you'll find this useful anyway, so that soon we'll have no need to write these boring "usages" by hand!