Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 11, 2017 What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
I don't quite understand what to do if getopt throws. I would have hoped for something like int arg1; string arg2; auto parser = getopt("opt1", "docstring 1", &arg1, "opt2", "docstring 2", &arg2); try { auto opts = parser.parse(args) } except(BadArguments) { parser.showHelpString(); } but instead, the docstring from getopt is only generated if all arguments are valid, i.e. when it's the least needed because the user already knew what to input. What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? |
December 11, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jordi Gutiérrez Hermoso | On 11-12-17 21:58, Jordi Gutiérrez Hermoso wrote: > but instead, the docstring from getopt is only generated if all arguments are valid, i.e. when it's the least needed because the user already knew what to input. > > What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? I would use something like this, print the help information for --help, print an error for invalid arguments: ``` try { auto helpInformation = getopt( args, "input|i", "The input", &input, "output|o", "The output", &output ); if (helpInformation.helpWanted) { defaultGetoptPrinter("Description", helpInformation.options); exit(0); } } catch (GetOptException e) { writeln(e.msg); exit(1); } ``` -- Mike Wey |
December 11, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wey | On Monday, 11 December 2017 at 21:24:41 UTC, Mike Wey wrote:
> On 11-12-17 21:58, Jordi Gutiérrez Hermoso wrote:
>> [...]
>
>
> I would use something like this, print the help information for --help, print an error for invalid arguments:
>
>
> ```
> try
> {
> auto helpInformation = getopt(
> args,
> "input|i", "The input", &input,
> "output|o", "The output", &output
> );
>
> if (helpInformation.helpWanted)
> {
> defaultGetoptPrinter("Description", helpInformation.options);
> exit(0);
> }
> }
> catch (GetOptException e)
> {
> writeln(e.msg);
> exit(1);
> }
> ```
D style would be to use sth. like this (instead of try/catch):
```
scope(failure) {
e.msg.writeln;
1.exit;
}
```
|
December 11, 2017 OT (Was: Re: What's the proper way to use std.getopt?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | On Mon, Dec 11, 2017 at 11:35:53PM +0000, Seb via Digitalmars-d-learn wrote: [...] > D style would be to use sth. like this (instead of try/catch): > > ``` > scope(failure) { > e.msg.writeln; > 1.exit; > } > ``` Frankly, much as I love UFCS syntax, I think this is taking it a little too far. Maybe I'm just old-fashioned, but I still find `exit(1)` much more readable than `1.exit`. Ditto for the writeln. scope(failure), OTOH, rawkz. :-P T -- Don't drink and derive. Alcohol and algebra don't mix. |
December 11, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wey | On Monday, 11 December 2017 at 21:24:41 UTC, Mike Wey wrote:
> try
> {
> auto helpInformation = getopt(
> args,
> "input|i", "The input", &input,
> "output|o", "The output", &output
> );
>
> if (helpInformation.helpWanted)
> {
> defaultGetoptPrinter("Description", helpInformation.options);
> exit(0);
> }
> }
> catch (GetOptException e)
> {
> writeln(e.msg);
> exit(1);
> }
But I would like to show the help docstring when processing the exception. It's pretty standard behaviour. If you give a program bad arguments, it just spits out a docstring of all options and what each does. Can this be achieved?
|
December 11, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jordi Gutiérrez Hermoso | On Monday, 11 December 2017 at 20:58:25 UTC, Jordi Gutiérrez Hermoso wrote:
> I don't quite understand what to do if getopt throws. I would have hoped for something like
I might have already said this to you on IRC but the way I'd do it (if you must do this) is:
void main(string[] args) {
int arg1;
string arg2;
bool getoptions(string[] args) {
auto result = getopt(args, "opt1", "docstring 1", &arg1, "opt2", "docstring 2", &arg2);
if(result.helpWanted)
defaultGetoptPrinter("Some information about the program.", result.options);
return result.helpWanted;
}
try {
if(getoptions(args))
return; // it just printed help
} catch(GetOptException e) {
writeln(e.msg);
getoptions(["--help"]);
return;
}
/* rest of your program */
}
Even though, I think printing the whole help output on any exception is likely to be fairly annoying since it obscures the actual error message.
|
December 11, 2017 Re: OT (Was: Re: What's the proper way to use std.getopt?) | ||||
---|---|---|---|---|
| ||||
On Monday, December 11, 2017 15:38:44 H. S. Teoh via Digitalmars-d-learn wrote:
> On Mon, Dec 11, 2017 at 11:35:53PM +0000, Seb via Digitalmars-d-learn wrote: [...]
>
> > D style would be to use sth. like this (instead of try/catch):
> >
> > ```
> > scope(failure) {
> >
> > e.msg.writeln;
> > 1.exit;
> >
> > }
> > ```
>
> Frankly, much as I love UFCS syntax, I think this is taking it a little too far. Maybe I'm just old-fashioned, but I still find `exit(1)` much more readable than `1.exit`. Ditto for the writeln.
Clearly, there's quite a range of what folks like or find acceptable. Personally, I never drop the parens unless it makes sense to treat the function like a property, so even if I were doing something like Seb here, it would be
e.msg.writeln();
1.exit();
but like you, I wouldn't use UFCS here. I don't know exactly what the line is for me though; some functions just don't feel right with UFCS, and others are perfectly fine. I think that part of it is probably whether the function returns. I'm unlikely to use UFCS if the function is void like these are. For whatever reason, using UFCS with something like writeln or exit just seems really wrong to me. But then again, I also think that it feels really wrong to do something like 42.msecs or 42.msecs(), and that _does_ return a value. Maybe it's because it feels like a constructor to me, and you don't use UFCS with constructors. I don't know. I don't know how logical or consistent my reasoning is with when to use UFCS, since I've never sat down and studied it. Sometimes, it feels perfectly reasonable, and other times, it just feels really wrong.
Either way, clearly, different folks have a different level of tolerance or liking for UFCS in various circumstances.
- Jonathan M Davis
|
December 12, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | On 12-12-17 00:35, Seb wrote: > D style would be to use sth. like this (instead of try/catch): > > ``` > scope(failure) { > e.msg.writeln; > 1.exit; > } > ``` I might have missed something, but where is `e` defined in this case? -- Mike Wey |
December 12, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jordi Gutiérrez Hermoso | On Monday, 11 December 2017 at 20:58:25 UTC, Jordi Gutiérrez Hermoso wrote: > What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? The command line tools I published use the approach described in a number of the replies, but with a tad more structure. It's hardly perfect, but may be useful if you want more examples. See: https://github.com/eBay/tsv-utils-dlang/blob/master/tsv-sample/src/tsv-sample.d. See the main() routine and the TsvSampleOptions struct. Most of the tools have a similar pattern. --Jon |
December 12, 2017 Re: What's the proper way to use std.getopt? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jon Degenhardt | On Tuesday, 12 December 2017 at 20:57:28 UTC, Jon Degenhardt wrote: > On Monday, 11 December 2017 at 20:58:25 UTC, Jordi Gutiérrez Hermoso wrote: >> What's the proper style, then? Can someone show me a good example of how to use getopt and the docstring it automatically generates? [snip] > See: > https://github.com/eBay/tsv-utils-dlang/blob/master/tsv-sample/src/tsv-sample.d Oh, thanks! This is more or less what I wanted. I suppose showing all of the docstring when the arguments are bad is possibly stupid and I shouldn't be doing that to begin with. I'll adopt this style to only show which argument was bad. |
Copyright © 1999-2021 by the D Language Foundation