Recovering options to getopt after a GetOptException is raised
Andrew Pennebaker
andrew.pennebaker at gmail.com
Sat Dec 8 19:58:16 UTC 2018
On Wednesday, 7 October 2015 at 17:15:17 UTC, Charles McAnany
wrote:
> Friends,
>
> I'm a bit puzzled by the behavior of this code:
>
> import std.getopt;
> import std.stdio;
>
> void main(string[] args){
> string val;
> GetoptResult opts;
> try{
> opts = getopt(args, std.getopt.config.required, "val",
> "value you need to specify", &val);
> }catch(GetOptException e){
> writeln("You idiot. You had to give these options:");
> writeln(opts.options);
> }
> }
>
> Expected result:
> :) programName --without --correct --argument
> You idiot. You had to give these options:
> --val value you need to specify
>
> Actual result:
> :) programName --without --correct --argument
> You idiot. You had to give these options:
> []
>
> It seems that the exception is thrown as soon as a missing
> option is encountered. It would be nice if getopt would
> populate GetoptResult.options before it threw the exception,
> because it would make the above code work smoothly.
> Alternatively, GetOptException could get a field containing the
> documentation that was provided in the call to getopt:
>
> catch(GetOptException e){
> writefln("You idiot. You didn't provide the required %s
> argument (%s)", e.optionName, e.optionDocumentation);
> }
>
> If there is a way to handle this cleanly, I'd appreciate it. As
> it is, std.getopt.config.required seems like it's not very
> useful because it emits a rather unhelpful error message
> (containing only the name of the missing option) and I can't
> see a way to print a more useful message without checking all
> the options in my own code.
>
> Cheers,
> Charles.
Yup, I just came across the same problem. D's getopt() is silly.
GetoptException could have included a field representing the
option specification, for use with defaultGetoptPrinter(); Or
getopt() could have printed the -h usage and exit()'ed; Or
std.getopt could have separated option specification construction
vs. validation into distinct function calls, so that the spec
could be bound to a variable for later use in printing the help
message when a parse error might occur.
But D's getopt doesn't do any of these things! Not the most
helpful. If D at least had splats like Ruby, then we could copy
the inputs that would go into the getopt() call to an array, and
reuse that spec, with a ["-h"] array of user arguments, to
actually print out a help message.
Or, programmers can manually re-type the getopt() spec, yuck!
Or, I can imagine adding a loop around the try/catch, so that a
failure sets a "fail" boolean and changes the user arguments to
["-h"].
For me, I have to gauge how much time I want to spend cleaning up
the stack trace-style usage message on invalid user input,
against more productive use of my time.
By the way, the getopt() documentation seems to suggest that when
users supply "-h|--help", that a usage banner is automatically
printed. But in fact, the programmer must manually check the
.helpWanted field on the result and manually run
defaultGetoptPrinter(). Lame!
More information about the Digitalmars-d
mailing list