Optional Parameter value?

940 views
Skip to first unread message

Kamil Kalinowski

unread,
Oct 28, 2012, 6:49:57 PM10/28/12
to jcomm...@googlegroups.com
Hi,

is there any way of defining Parameter which can have optional value after it? 

E.g. if i run my program like this:
$ app --report
I indicate that it needs to generate report to it's default reports directory defined somwhere in config. On the other hand, when I type
$ app --report other-dir
I'd like it to take this argument and generate report in other-dir directory.

I know that I could use another parameter for indicating directory but I'm looking for prettier solution. Is it possible with jcommader? 

Thanks in advance for your help,
Kamil

Cédric Beust ♔

unread,
Oct 28, 2012, 11:47:48 PM10/28/12
to jcomm...@googlegroups.com
Yes, with variable arities:


-- 
Cédric

Kamil Kalinowski

unread,
Oct 29, 2012, 5:08:43 AM10/29/12
to jcomm...@googlegroups.com
Yes, I tried it before asking this question, but when I run app without value after it I get parameter Exception: Expected value after parameter --report

Cédric Beust ♔

unread,
Oct 29, 2012, 11:56:19 AM10/29/12
to jcomm...@googlegroups.com
Well, there should be at least one value. If there are no values, why even specify -report at all?

-- 
Cédric

Kamil Kalinowski

unread,
Oct 29, 2012, 4:29:30 PM10/29/12
to jcomm...@googlegroups.com, ced...@beust.com
Like I said in first message - just to indicate that it should perform additional action, like generating report.
So, you can run it like that, only showing tests resutls on the screen :
app test --list-of-tests file.txt --jar tests.jar

or(indicating that it should generate report, with default name, filetype and path):
app test --list-of-tests file.txt --jar tests.jar --report

or(indicating that it should generate XML report  of name 'report' in current directory)
app test --list-of-tests file.txt --jar tests.jar -report report.xml

I hope I made myself clear ;)

Adam Haselhuhn

unread,
Feb 13, 2015, 11:27:18 PM2/13/15
to jcomm...@googlegroups.com, ced...@beust.com
I realize this is an old topic, but I would also like to see support for parameters with an optional argument. 

My use case is that I have an option which indicates that a certain operation is to be performed on the inputs.  I would like to add an optional argument pointing to the location of a file which specifies a subset of the inputs on which this operation should be run.

So in other words, "-operation" would specify to run the operation on all inputs, while "-operation=file.txt" would indicate that the operation would only run on the inputs listed in file.txt.

Adam

Cédric Beust ♔

unread,
Feb 13, 2015, 11:41:36 PM2/13/15
to Adam Haselhuhn, jcomm...@googlegroups.com

Hi Adam,

For what it’s worth, this is exactly the kind of “poor command line practices” that I don’t want to encourage with JCommander. You are describing two very different behaviors for your tool, you should create two separate options for them, one -operation=<file> and one -allInputs.

Adam Haselhuhn

unread,
Feb 14, 2015, 12:15:05 AM2/14/15
to jcomm...@googlegroups.com, cyal...@gmail.com, ced...@beust.com
Thanks for the quick response.

I understand what you're saying, and I suspected this was an intentional design decision, especially considering many other command line parsers allow optional arguments.

The tool I'm working on performs multiple operations, this particular optional operation is only one of them.  As such, I don't think your suggestion is quite appropriate, but there are other similar approaches that would work.

If you have time, and for my education, what exactly about the syntax I was describing would be poor command line practice?  I don't see them as being "very different behaviors".

Adam

Cédric Beust ♔

unread,
Feb 14, 2015, 12:56:39 AM2/14/15
to Adam Haselhuhn, jcomm...@googlegroups.com
Hi Adam,

Fundamentally, I think that these two operations have a different type: one is a boolean, the other takes a file. It's not just philosophical: because JCommander maps these options directly to Java field types, I don't see how this could be encoded at all. The fact that JCommander forces you to bind these two options to two different types (by requiring different names) is, in my opinion, a good thing that leads to a command line interface that's less confusing.



-- 
Cédric

Paolo Di Tommaso

unread,
Feb 14, 2015, 11:21:49 AM2/14/15
to jcomm...@googlegroups.com, cyal...@gmail.com, ced...@beust.com
Several times I needed this feature, and I had to implement terrible hacks to handle it. 


In my opinion a library should be flexible enough to help users and should not try to *moralise* their coding, above all if its motto is "Because life is too short to parse command line parameters" 


Best,
Paolo

Cédric Beust ♔

unread,
Feb 14, 2015, 1:31:47 PM2/14/15
to Paolo Di Tommaso, jcomm...@googlegroups.com, Adam Haselhuhn

Again, how would you even use this in JCommander?

Your fields have different types (one is boolean, the other is a File or a String) but both have the name "operation". Show me what your args class would look like.


-- 
Cédric

Paolo Di Tommaso

unread,
Feb 16, 2015, 5:06:43 AM2/16/15
to jcomm...@googlegroups.com, paolo.d...@gmail.com, cyal...@gmail.com, ced...@beust.com
This can be managed returning an "optional" value if the user does not specify it on the command line option. 

For example it could be possible define a parameter as shown below: 

@Parameter( names="--flag", optional="foo" ) 
String flag;


With the following semantic:

no flag => flag == null
--flag => "foo" 
--flag Salut => "Salut"



Cheers,

Adam Haselhuhn

unread,
Feb 16, 2015, 9:26:36 AM2/16/15
to jcomm...@googlegroups.com, paolo.d...@gmail.com, cyal...@gmail.com, ced...@beust.com
From my point of view, the options have the same basic type:  the list of inputs to operate on.  In one case it is "all inputs" to the overall program, in the other it is a sublist of the inputs.  I could provide a second option to specify "all inputs", but I'd rather just have one option for the very similar functionality.

The way I would use this in JCommander is to have the field have a custom type with a custom string converter, and allow passing null to the string converter when an option argument is omitted:

public class ProgramOptions
{
  @Parameter (names="--operation", converter=OperationInputsConverter.class)
  private OperationInputs operationInputs;
  ...
}

public class OperationInputsConverter implements IStringConverter<OperationInputs>
{
  public OperationInputs convert(String value)
  {
    if (value == null)
    {
       // optional argument was not supplied.
    }
  }
}


Paolo's solution is better.  Like values provided by IDefaultProvider, the optional value could be passed to the string converter to construct the value for the default argument.

Al Le

unread,
Feb 16, 2015, 11:09:46 AM2/16/15
to jcomm...@googlegroups.com
I once had a somewhat similar situation. I needed an option which would require either three or six parameters. If only three are specified, the other three should get some default values. I even made a proposal how this could be accomplished, but it was not accepted.
 
I ended up using two different options (with different names of course), one with three and another with six params.
 
And now I think this is a better solution. Not too many things to screw up.
 
After the command line options are parsed by JCommander, I map them to my "business object" and apply the defafulting logic.
 
Cheers
AL
 
Gesendet: Montag, 16. Februar 2015 um 11:06 Uhr
Von: "Paolo Di Tommaso" <paolo.d...@gmail.com>
An: jcomm...@googlegroups.com
Cc: paolo.d...@gmail.com, cyal...@gmail.com, ced...@beust.com
Betreff: Re: [JCommander] Optional Parameter value?
--
You received this message because you are subscribed to the Google Groups "jcommander" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jcommander+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages