Skip to content

Conversation

burner
Copy link
Member

@burner burner commented Jul 15, 2015

}
cfg.required = false;

return getoptImpl(args, cfg, rslt, opts[lowSliceIdx .. $]);
getoptImpl(args, cfg, rslt, opts[lowSliceIdx .. $]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this kill the tail-call optimization?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see getopt being enough of bottleneck anywhere to care about micro-optimizations like tail-call here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not. I'm not a huge fan of allocating the exceptions without throwing them though.

@schveiguy
Copy link
Member

I think this can be handled easier by processing the --help option first (possibly outside the Impl function). Then you know while processing each parameter that --help has been passed or not.

@burner
Copy link
Member Author

burner commented Jul 15, 2015

if you handle help outside impl, the "not so new h|help" functionally would break legacy code, as currently the user can use h and help for anything they want. Changing that is not good IMO. Even if that would re-enable tail-call optimization, if it was present in the first place.

@schveiguy
Copy link
Member

This is possible to work around:

  1. check to see if any --help option exist in the options array (shouldn't be hard, search for "help|h" string)
  2. Do this:
if(helpIncluded)
   return getOptImpl(args, cfg, rslt, options);
else
   return getOptImpl(args, cfg, rslt, "help|h", "This help information.", () {rslt.helpWanted = true;}, options);

And you can avoid all the specific help code in the implementation.

This should be identical to current implementation result, but without triggering exception on --help. As it is, I think the way this is done is terrible. What if the app isn't written in English?

@burner
Copy link
Member Author

burner commented Jul 15, 2015

the searching part would require to iterate the complete input, properly recursive as it is done currently. I think the cure is worse than the disease (IMO it is not even a problem)

@schveiguy
Copy link
Member

the searching part would require to iterate the complete input, properly recursive as it is done currently.

No.

foreach(opt; options)
   static if(is(typeof(opt) == string))
      if(opt == "help|h") helpIncluded = true;

@schveiguy
Copy link
Member

Also note, the current code will add a "help" option at the end for displaying help, even if you have handled help on your own.

@burner
Copy link
Member Author

burner commented Jul 15, 2015

actually I think that is not the case the in-build help is only used if there are no more options to process but you still have arguments left.

@schveiguy
Copy link
Member

actually I think that is not the case

import std.getopt;

void main(string[] args)
{
    bool help;
    auto rslt = getopt(args, "help|h", "test help", &help);

    if (help)
    {
        defaultGetoptPrinter("Some information about the program.",
            rslt.options);
    }
}
$ ./testgetopt -h
Some information about the program.
-h --help test help
-h --help This help information.

@burner
Copy link
Member Author

burner commented Jul 16, 2015

hm, my bad

@schveiguy
Copy link
Member

Thinking about this some more. I really am kind of not liking that we handle unspecified required arguments with an exception. Even if we fix this, someone who handles --help on their own will be subject to the same issue.

I don't know a good way to fix this.

@quickfur quickfur changed the title fix issue14724 Fix issue 14724 - std.getopt: config.required breaks --help Jul 21, 2015
@quickfur
Copy link
Member

Updated PR title to be more descriptive.

@burner
Copy link
Member Author

burner commented Jul 21, 2015

@quickfur thanks

some nicer impl
@burner
Copy link
Member Author

burner commented Aug 16, 2015

@schveiguy @quickfur please have a look the tail recursion returned

@quickfur
Copy link
Member

LGTM.

@schveiguy
Copy link
Member

I'll merge, but I found another problem that will make this problem obsolete :) See https://issues.dlang.org/show_bug.cgi?id=14921

@schveiguy
Copy link
Member

Auto-merge toggled on

schveiguy added a commit that referenced this pull request Aug 17, 2015
Fix issue 14724 - std.getopt: config.required breaks --help
@schveiguy schveiguy merged commit 34a7fc5 into dlang:master Aug 17, 2015
CyberShadow added a commit to CyberShadow/phobos that referenced this pull request Oct 5, 2015
WalterBright added a commit that referenced this pull request Oct 6, 2015
std.getopt: Re-add constructor removed in PR #3489
WalterBright added a commit that referenced this pull request Oct 6, 2015
std.getopt: Re-add constructor removed in PR #3489
@burner burner deleted the issue14724 branch October 23, 2015 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants