September 02, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | 02-Sep-2013 09:32, H. S. Teoh пишет: > On Sat, Aug 31, 2013 at 07:29:42PM -0700, Jonathan M Davis wrote: >> On Saturday, August 31, 2013 19:18:11 Andrei Alexandrescu wrote: >>> I remember sitting next to Kirk McDonald at the D conference in 2007 >>> as he was showing me Python's argparse. I personally found pretty >>> much any example we could think of more verbose and uglier than >>> std.getopt. >> >> std.getopt is definitely lacking some nice-to-have features (like >> automatically generating --help from the options), but for the most >> part, I don't think that it can be improved much without seriously >> complicating it. I think that it's about at the limit of what can be >> done and still have it be simple, and it works really well for the >> most part, so if we haven't hit the sweet spot, we're at least close. >> I've toyed with trying to figure out how to improve it, but I think >> that doing so cleanly would be very hard. > > I've had several people complain to me about std.getopt not > understanding / supporting "standard" command-line syntax. Like '-c5' > vs. '-c 5'. I've also experienced some quirks in how it handles option > parsing, such as being unable to distinguish between '-w' and '--water' > where both are distinct options (the use case is that multiple options > begin with 'w', but one is more common than the others so '-w' is > desirable as a shorthand, but currently std.getopt support for this is > sketchy and unreliable). > Last time I tried (about a year or so ago) I was frustrated with how rigid and strange it was. In the end I just rolled back to some hacks like to!int(args[1]) and so on. At least that was under my control. -- Dmitry Olshansky |
September 02, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | I see strong points on both sides. Maybe it would be a good thing to really have two versions with the second one ("getOpts") getting the options in arrays (as introduced above). Like that the "simple" version we have now could, besides some minor corrections, stay like it is and not disturb existing programs using it. The second version would be the "bigger" one with help, valid ranges, eval funcs, and other goodies as identified by a crowd discussed wish list (and "auto help print" controlled e.g. by a flag). A+ -R |
September 02, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ramon | On Mon, Sep 02, 2013 at 09:28:37PM +0200, Ramon wrote: > I see strong points on both sides. Maybe it would be a good thing to really have two versions with the second one ("getOpts") getting the options in arrays (as introduced above). Like that the "simple" version we have now could, besides some minor corrections, stay like it is and not disturb existing programs using it. The second version would be the "bigger" one with help, valid ranges, eval funcs, and other goodies as identified by a crowd discussed wish list (and "auto help print" controlled e.g. by a flag). [...] Actually, I think it's possible to please both sides with a single implementation. If we use what was suggested, and add an optional string parameter per option to serve as a help string, then that takes care of the auto help functionality. For checking ranges and stuff, we already support delegates passed to getopt, for example: void main(string[] args) { int size; getopt(args, "-s", (int s) { enforce(s >= 10 && s < 20); size = s; } ); } So we just need to provide a few commonly-used range-checking option parsers and we're good to go. For example, with the proposed enhancements, we could write: void main(string[] args) { enum A { Aa, Ab, Ac }; A a; int size; getopt(args, "-a", &a, "Type of data to generate", "-s", checkBounds(&size, 10, 20), "Size of input" ); } Where checkBounds (that is, std.getopt.checkBounds) is defined something like this: auto checkBounds(T)(T* targetVar, T lowerBound, T upperBound) { // Returns a delegate usable by the current version of // getopt. return (string optValue) { auto val = to!T(optValue); enforce(val >= lowerBound && val < upperBound); *targetVar = val; }; } Other similar helpers that can parse lists, arrays, etc., can be provided by std.getopt, so that user code will never have to re-implement any of this boilerplate by hand. T -- IBM = I'll Buy Microsoft! |
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On 9/2/13 9:58 AM, Dmitry Olshansky wrote:
> Last time I tried (about a year or so ago) I was frustrated with how
> rigid and strange it was.
> In the end I just rolled back to some hacks like to!int(args[1]) and so
> on. At least that was under my control.
std.getopt implements simple and widely used command-line options. If you used to!int(args[1]) that's not an option, it's a straight argument that getopt will let pass through unchanged.
Andrei
|
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 9/2/13 7:16 AM, Andrej Mitrovic wrote:
> On 9/2/13, Jacob Carlborg <doob@me.com> wrote:
>> This is a simple idea:
>>
>> uint timeout;
>> getopt(args, "timeout|t", &timeout).help("Set the timeout");
>
> W.r.t. help strings, I would prefer if we could instead use:
>
> getopt(args,
> "timeout|t", &timeout, "Set the timeout",
> "other", &other, // note: no comment!
> "flag|f", &flag, "Set the flag")
>
> I think we could make getopt support this. For example:
>
> ["foo", &foo] => name, field
> ["foo", &foo, "foo text"] => name, field, #3 is a comment
> ["foo", &foo, "foo text", "bar", &bar] => #3 is a commen
> ["foo", &foo, "foo text", &bar] => #3 is a new name
>
> Essentially all getopt has to do is slice up the arguments into
> groups, where an address and the string before it begin a new group.
>
> @Andrei: What do you think?
Sounds great. There's a related bugzilla entry IIRC.
Andrei
|
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/3/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Sounds great. There's a related bugzilla entry IIRC. There was this: http://d.puremagic.com/issues/show_bug.cgi?id=3780 And a pull: https://github.com/D-Programming-Language/phobos/pull/1030 However I think that pull request is over-reaching. We should improve getopt incrementally, where each pull adds one feature. If huge additions and rewrites are needed then a DIP should be made first, especially since the pull wanted to break code. |
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/3/13 8:20 AM, Andrei Alexandrescu wrote: > On 9/2/13 7:16 AM, Andrej Mitrovic wrote: >> On 9/2/13, Jacob Carlborg <doob@me.com> wrote: >>> This is a simple idea: >>> >>> uint timeout; >>> getopt(args, "timeout|t", &timeout).help("Set the timeout"); >> >> W.r.t. help strings, I would prefer if we could instead use: >> >> getopt(args, >> "timeout|t", &timeout, "Set the timeout", >> "other", &other, // note: no comment! >> "flag|f", &flag, "Set the flag") >> >> I think we could make getopt support this. For example: >> >> ["foo", &foo] => name, field >> ["foo", &foo, "foo text"] => name, field, #3 is a comment >> ["foo", &foo, "foo text", "bar", &bar] => #3 is a commen >> ["foo", &foo, "foo text", &bar] => #3 is a new name >> >> Essentially all getopt has to do is slice up the arguments into >> groups, where an address and the string before it begin a new group. >> >> @Andrei: What do you think? > > Sounds great. There's a related bugzilla entry IIRC. > > Andrei Yep, that's the one. http://d.puremagic.com/issues/show_bug.cgi?id=3780. Thanks for looking into it, Andrej. Andrei |
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 9/3/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Yep, that's the one. http://d.puremagic.com/issues/show_bug.cgi?id=3780. Another impotant note to make is that the pull for #3780 was made before UDAs were available. Now that we have them, we can make a more reliable and readable API rather than have to depend on argument position rules. For example: getopt(args, "count", &count, @doc("This is the thread count")); |
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 03-Sep-2013 18:44, Andrei Alexandrescu пишет: > On 9/2/13 9:58 AM, Dmitry Olshansky wrote: >> Last time I tried (about a year or so ago) I was frustrated with how >> rigid and strange it was. >> In the end I just rolled back to some hacks like to!int(args[1]) and so >> on. At least that was under my control. > > std.getopt implements simple and widely used command-line options. If > you used to!int(args[1]) that's not an option, it's a straight argument > that getopt will let pass through unchanged. > Well that bit about to!int(args[1]) was somewhat tongue in cheek, I can't recall the details now anyway. To sum up my experience I tried to for a few hours, it didn't quite work the way I wanted (nor I've found a way to tweak it through) so I dropped it. Looking at it now I think the key feature missing is automatic generation of the summary of switches. std.getopt loses a lot of charm by not automating this part of the job (maintained by hand the summary would get out of sync sooner or later). -- Dmitry Olshansky |
September 03, 2013 Re: obsolete D libraries/modules | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 2013-09-03 18:43, Andrej Mitrovic wrote: > getopt(args, > "count", &count, @doc("This is the thread count")); That's a lot better, but it still needs to match the help text to the flag. -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation