You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by "David M. Karr" <da...@gmail.com> on 2016/02/02 20:42:27 UTC

Example of CliBuilder with "optionalArg: true"?

Because someone asked me a question about it, I was looking at 
CliBuilder, for a scenario where "optionalArg" is true, and to get the 
value of the option, or detect that it's not present.  I've looked at 
the groovydoc, and CliBuilderTest, but it's not clear to me how this works.

Re: Example of CliBuilder with "optionalArg: true"?

Posted by Paul King <pa...@asert.com.au>.
I think we had some improved handling for optional args in some spikes
we did for newer versions of the CLI processing stuff. But none of
that has been taken forward yet.

In the interim, you can peek at return types as per your examples
above or sneak down into the underlying implementation - just realise
that we don't make any guarantees about future breaking changes if you
do start using the underlying methods. It would look something like:


if (options.f) {
  def f = options.getOptionValue('f')
  if (f) println "found arg $f"
  else println "flag set with no optional arg"
}

And you'd have to manage calling getOptionValues where needed too.

Cheers, Paul.


On Tue, Feb 9, 2016 at 8:33 AM, David M. Karr
<da...@gmail.com> wrote:
> On 02/08/2016 09:11 AM, Russel Winder wrote:
>>
>> On Tue, 2016-02-02 at 19:56 +0000, KARR, DAVID wrote:
>> […]
>>>
>>> With a  simple script like this:
>>> ----------------
>>> def cli = new CliBuilder()
>>> cli.with {
>>>    f(args: 1, optionalArg: true, "set a value")
>>> }
>>> def options = cli.parse(args)
>>> def fval = options.f
>>> println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
>>> def fvalue = options.fs
>>> println "fvalue[" + fvalue + "]"
>>> ---
>>>
>>> If I run this with "-f abc", I get:
>>> --------------
>>> fval[abc] class[java.lang.String]
>>> fvalue[[abc]]
>>> ----------------
>>>
>>> But if I run it with "-f", I get:
>>> ------------
>>> fval[true] class[java.lang.Boolean]
>>> fvalue[true]
>>> -------------
>>
>> And if you run without -f on the command line you get:
>>
>> fval[false] class[java.lang.Boolean]
>> fvalue[false]
>>
>> So I think we are looking at this being a feature of options with the
>> optionalArg property set. Without it not having an argument to -f
>> fails.
>>
>>> I suppose I could hack something with this information, but I would
>>> think there would be something more explicit to tell me whether an
>>> argument was supplied for the option.
>>
>> Thinking about this, I would say it is right that this behaviour is a
>> feature, and that it is what the code has asked for: an option that can
>> deliver presence or a value. When the is a value deliver it, otherwise
>> deliver a Boolean stating whether the flag was present.
>>
>> Clearly managing this type of option is non-trivial, but I think this
>> is not a bug.
>>
> Thanks for doing that analysis.
>
> Whether it's a bug is debatable, but I think it's clear that overloading
> behaviors often create confusion.  A friendlier interface would separate the
> notion of "presence of the option" from "value of the argument".  However,
> doing that might make all references to options more verbose, which is
> certainly not ideal.
>
> I suppose an improvement could be made by just putting a little pseudocode
> algorithm in the doc that shows how you would either retrieve a value if
> it's present, or determine it's not there, I suppose by checking the class
> of the value returned from "options.<option>".  The only time you have a
> value is when the class is "java.lang.String".  Would that be correct?

Re: Example of CliBuilder with "optionalArg: true"?

Posted by "David M. Karr" <da...@gmail.com>.
On 02/08/2016 09:11 AM, Russel Winder wrote:
> On Tue, 2016-02-02 at 19:56 +0000, KARR, DAVID wrote:
> […]
>> With a  simple script like this:
>> ----------------
>> def cli = new CliBuilder()
>> cli.with {
>>    f(args: 1, optionalArg: true, "set a value")
>> }
>> def options = cli.parse(args)
>> def fval = options.f
>> println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
>> def fvalue = options.fs
>> println "fvalue[" + fvalue + "]"
>> ---
>>
>> If I run this with "-f abc", I get:
>> --------------
>> fval[abc] class[java.lang.String]
>> fvalue[[abc]]
>> ----------------
>>
>> But if I run it with "-f", I get:
>> ------------
>> fval[true] class[java.lang.Boolean]
>> fvalue[true]
>> -------------
> And if you run without -f on the command line you get:
>
> fval[false] class[java.lang.Boolean]
> fvalue[false]
>
> So I think we are looking at this being a feature of options with the
> optionalArg property set. Without it not having an argument to -f
> fails.
>
>> I suppose I could hack something with this information, but I would
>> think there would be something more explicit to tell me whether an
>> argument was supplied for the option.
> Thinking about this, I would say it is right that this behaviour is a
> feature, and that it is what the code has asked for: an option that can
> deliver presence or a value. When the is a value deliver it, otherwise
> deliver a Boolean stating whether the flag was present.
>
> Clearly managing this type of option is non-trivial, but I think this
> is not a bug.
>
Thanks for doing that analysis.

Whether it's a bug is debatable, but I think it's clear that overloading 
behaviors often create confusion.  A friendlier interface would separate 
the notion of "presence of the option" from "value of the argument".  
However, doing that might make all references to options more verbose, 
which is certainly not ideal.

I suppose an improvement could be made by just putting a little 
pseudocode algorithm in the doc that shows how you would either retrieve 
a value if it's present, or determine it's not there, I suppose by 
checking the class of the value returned from "options.<option>".  The 
only time you have a value is when the class is "java.lang.String".  
Would that be correct?

Re: Example of CliBuilder with "optionalArg: true"?

Posted by Russel Winder <ru...@winder.org.uk>.
On Tue, 2016-02-02 at 19:56 +0000, KARR, DAVID wrote:
> > 
[…]
> With a  simple script like this:
> ----------------
> def cli = new CliBuilder()
> cli.with { 
>   f(args: 1, optionalArg: true, "set a value")
> }
> def options = cli.parse(args)
> def fval = options.f
> println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
> def fvalue = options.fs
> println "fvalue[" + fvalue + "]"
> ---
> 
> If I run this with "-f abc", I get:
> --------------
> fval[abc] class[java.lang.String]
> fvalue[[abc]]
> ----------------
> 
> But if I run it with "-f", I get:
> ------------
> fval[true] class[java.lang.Boolean]
> fvalue[true]
> -------------

And if you run without -f on the command line you get:

fval[false] class[java.lang.Boolean]
fvalue[false]

So I think we are looking at this being a feature of options with the
optionalArg property set. Without it not having an argument to -f
fails.

> I suppose I could hack something with this information, but I would
> think there would be something more explicit to tell me whether an
> argument was supplied for the option.

Thinking about this, I would say it is right that this behaviour is a
feature, and that it is what the code has asked for: an option that can
deliver presence or a value. When the is a value deliver it, otherwise
deliver a Boolean stating whether the flag was present.

Clearly managing this type of option is non-trivial, but I think this
is not a bug.

-- 
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net
41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


Re: Example of CliBuilder with "optionalArg: true"?

Posted by "David M. Karr" <da...@gmail.com>.
On 02/05/2016 11:27 PM, Russel Winder wrote:
> On Tue, 2016-02-02 at 19:56 +0000, KARR, DAVID wrote:
> […]
>> With a  simple script like this:
>> ----------------
>> def cli = new CliBuilder()
>> cli.with {
>>    f(args: 1, optionalArg: true, "set a value")
>> }
>> def options = cli.parse(args)
>> def fval = options.f
>> println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
>> def fvalue = options.fs
>> println "fvalue[" + fvalue + "]"
>> ---
>>
>> If I run this with "-f abc", I get:
>> --------------
>> fval[abc] class[java.lang.String]
>> fvalue[[abc]]
>> ----------------
>>
>> But if I run it with "-f", I get:
>> ------------
>> fval[true] class[java.lang.Boolean]
>> fvalue[true]
>> -------------
>>
>> I suppose I could hack something with this information, but I would
>> think there would be something more explicit to tell me whether an
>> argument was supplied for the option.
> CliBuilder is a very thin wrapper around commons.cli, it is basically
> just an adapter with little or no functionality of its own. I posit
> therefore that what you are seeing is just the behaviour stemming from
> commons.cli, or if not then it is a bug.

Yes, I realized that later.  I posed basically the same question to the 
commons user list, but I didn't get any reply.
>
> I'll see if I can have a play with this this weekend.
>


Re: Example of CliBuilder with "optionalArg: true"?

Posted by Russel Winder <ru...@winder.org.uk>.
On Tue, 2016-02-02 at 19:56 +0000, KARR, DAVID wrote:
> > 
[…]
> With a  simple script like this:
> ----------------
> def cli = new CliBuilder()
> cli.with { 
>   f(args: 1, optionalArg: true, "set a value")
> }
> def options = cli.parse(args)
> def fval = options.f
> println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
> def fvalue = options.fs
> println "fvalue[" + fvalue + "]"
> ---
> 
> If I run this with "-f abc", I get:
> --------------
> fval[abc] class[java.lang.String]
> fvalue[[abc]]
> ----------------
> 
> But if I run it with "-f", I get:
> ------------
> fval[true] class[java.lang.Boolean]
> fvalue[true]
> -------------
> 
> I suppose I could hack something with this information, but I would
> think there would be something more explicit to tell me whether an
> argument was supplied for the option.

CliBuilder is a very thin wrapper around commons.cli, it is basically
just an adapter with little or no functionality of its own. I posit
therefore that what you are seeing is just the behaviour stemming from
commons.cli, or if not then it is a bug.

I'll see if I can have a play with this this weekend.

-- 
Russel.
=============================================================================
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net
41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


RE: Example of CliBuilder with "optionalArg: true"?

Posted by "KARR, DAVID" <dk...@att.com>.
> -----Original Message-----
> From: David M. Karr [mailto:davidmichaelkarr@gmail.com]
> Sent: Tuesday, February 02, 2016 11:42 AM
> To: users@groovy.apache.org
> Subject: Example of CliBuilder with "optionalArg: true"?
> 
> Because someone asked me a question about it, I was looking at
> CliBuilder, for a scenario where "optionalArg" is true, and to get
> the
> value of the option, or detect that it's not present.  I've looked
> at
> the groovydoc, and CliBuilderTest, but it's not clear to me how
> this works.

Adding to this from my alter ego. :)

With a  simple script like this:
----------------
def cli = new CliBuilder()
cli.with { 
  f(args: 1, optionalArg: true, "set a value")
}
def options = cli.parse(args)
def fval = options.f
println "fval[" + fval + "] class[" + fval.getClass().getName() + "]"
def fvalue = options.fs
println "fvalue[" + fvalue + "]"
---

If I run this with "-f abc", I get:
--------------
fval[abc] class[java.lang.String]
fvalue[[abc]]
----------------

But if I run it with "-f", I get:
------------
fval[true] class[java.lang.Boolean]
fvalue[true]
-------------

I suppose I could hack something with this information, but I would think there would be something more explicit to tell me whether an argument was supplied for the option.