Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

access to detected options collection #9

Closed
cwensel opened this Issue · 9 comments

2 participants

@cwensel

Would be useful to have access to a collection of the detected options as OptionSpec (and/or String).

This would allow for simple set operations like detecting if some sub-set of N options were set vs using #has && #has N times.

Might also be useful to iterate detected options, like when populating intermediate pojos.

Retaining order in which they were detected would be interesting (no immediate need on this end though)

Distinguishing sets of options having arguments and without arguments (not defaults) would also be useful.

For me, sometimes having arguments and not having them means different things. Set operations on each may simplify my argument checking code etc.

thanks!
chris

@pholser
Owner

This sounds interesting -- I think doing what we can to reduce arg-checking boilerplate might be the most useful direction in which to take the library. Do you have a particular API in mind? Examples which would use said API?

@cwensel

I'd probably be happy with:

List<OptionSpec<?>> getAllDetectedOptions();
List<OptionSpec<?>> getNoArgDetectedOptions();
List<OptionSpec<?>> getWithArgDetectedOptions(); // explicit args on options, not defaults

List would be interesting as you could retain order, and duplicates (same option twice turns option off, in some use-cases)

At this moment in my app I'm wanting to know if just two options, were set and no others.

JUST_LIST_NAMES.containsAll( #getAllDetectedOptions() ) == true // then we list all names, and no other opts were set
@cwensel

I should add I do this a lot:

  protected boolean hasWithoutArgument( OptionSpec type )
    {
    return optionSet.has( type ) && !optionSet.hasArgument( type );
    }

below would be equivalent. but the above on OptionSet would also be useful shorthand..

#getNoArgsDetectedOptions().contains( type ) 
@cwensel

oh, and this too

  protected boolean doesNotHave( OptionSpec... specs )
    {
    for( OptionSpec spec : specs )
      {
      if( optionSet.has( spec ) )
        return false;
      }

    return true;
    }
@pholser
Owner

I'm thinking of something more fluent and ambitious:

OptionSet options = parser.parse(args);
List<OptionSpec<?>> detected = options.that(...);

where:

interface OptionMatcher {
    boolean matches(OptionSpec<?> spec, OptionSet detected);
}

class OptionSet {
    List<OptionSpec<?>> that(OptionMatcher matcher) {
        // ...
    }
}

Supposing OptionSpec is fitted with methods that let you decide whether the option can accept an argument, etc., and perhaps a utility class OptionMatchers exposes some common matchers to get one started...I think we'd end up with something nice. An algebra for detected options, if you will.

I'll explore this over the next little while.

@pholser
Owner

On the other hand, that may be overthinking it. I am leaning toward offering OptionSet#specs() : List> but probably not the other two. With the first one at least has the building blocks from which to construct the first and second which, so far as I can tell, are uncommon enough that I'd rather not add them to OptionSet's API.

How does that sound?

@cwensel

Access to the detected options is sufficient. thanks!

@pholser
Owner

Let me know what you think -- I called the method OptionSpec#specs. "options" is maybe a bit overloaded by now.

@cwensel

That should work great, thanks!

@cwensel cwensel closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.