no matter what you pass through command line
@chenhayat sorry you’re seeing a problem.
Would you be kind as to post a reproduction step and sample code that includes your options class and the parser invocation code? We’d be able to help better in that case.
Thanks
Hi ericnewton76,
public class Options
{
[Option("fail_condition", HelpText = "true|false. when false - if a condition lacks permutations- program will not throw exception, only print warning", Default = true)]
public bool ShouldFailCondition { get; set; }
}
In Main program:
private static bool ShouldFailCondition { get; set; }
public static int RunOptionsAndReturnExitCode(Options options)
{
ShouldFailCondition = options.ShouldFailCondition;
return 0;
}
static void Main(string[] args)
{
var results = CommandLine.Parser.Default.ParseArguments<Options>(args)
.WithParsed<Options>(opts => RunOptionsAndReturnExitCode(opts))
.WithNotParsed<Options>((errs) => { });
// ShouldFailCondition value will we true - no matter what you pass
}
Then I run the program: MyProgram.exe --fail_condition false
However- shouldFailCondition gets true.
Thanks :)
I've confirmed this behavior too.
Booleans do not take arguments. They are flags, so including the boolean flag means 'true' and leaving it out means 'false'.
@nemec
I'm sure there are cases where you want the boolean to be default True, and you want to give the user the ability to set it to False.
It's common to provide an option that begins with --no when disabling behavior that defaults to 'on' or 'true'. Sometimes tools use an uppercase short-code to disable an option as well, e.g. -g explicitly enables groups and -G disables them.
Example of a long option: --no-should-fail-condition or --disable-fail-condition.
https://www.gnu.org/software/wget/manual/wget.html#Directory-Options
http://linuxcommand.org/lc3_man_pages/ls1.html
https://curl.haxx.se/docs/manpage.html#--no-keepalive
Making the parameter a nullable boolean worked for me
This is a feature (bool options!) that it makes sense to be designed as it is, even though said design may look counterintuitive to some: bool options MUST be decorated as Required=False.
As Dan Nemec has clearly stated earlier in this thread, bool options are just flags. As such, it makes a lot of sense for the dev team to be able to choose the Default value for any given bool option on a case-by-case basis, so, to be able to have that, bool options ALSO MUST be decorated as Required=False.
Once you declare your bool options with the proper decoration Required=False and the proper Default value, this type of option works as smooth & perfect as it should.
Kind regards, GEN
PS:
To make my point clear, I include an example of a bool option that I use on one of my projects:
[Option ( 'i', "IsRegexSearch", Required = false, Default = true, HelpText = "Is a Regex Search." )]
public bool IsRegexSearch
{
get;
set;
}
The Usage screen turns out to be as follows (I include only the Usage for the bool option!)
-i, --IsRegexSearch (Default: true) Is a Regex Search.
I too looked for some time to temporary switch a bool parameter to False, to no avail.
What would be the drawback of having the ability to set a boolean param to false either by omitting it (as currently) OR by explicitly setting it to false?
Making the parameter a nullable boolean worked for me
@DennisTycho but in this case the boolean value always required. See my issue about nullable bools: https://github.com/commandlineparser/commandline/issues/316
I can confirm that the behavior of bool option in v2.3 is working fine
I have did a demo test using v2.3 and found the following behaviour with duming the option class:
Check the demo test
1)with removing default
-------Without Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : False
-------Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : True
2)With default=true
-------Without Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : True
-------Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : True
3)With default=false
-------Without Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : False
-------Passing Parameter-------
Dumping object(Options)
ShouldFailCondition : True
@moh-hassan, as @nemec said it's common to provide an option that begins with --no when disabling behavior that defaults to 'on' or 'true' (e.g. --feature or --no-feature).
I think it could be extremely comfortable for all, if the library automatically supported this --no syntax for bool options. This would allow users to define any default value for bool options.
It also can be configurable (user can turn the behavior off when not desired, similar to how option case-sensitivity can be controlled).
As regarding to nullable-bool mentioned in #316, I think it would fit great into this model. If --feature or --no-feature was specified, or default value supplied, the option is set. Otherwise, it stays null. I find the today's bool? behavior, that requires explicit true/false value in the command line, completely user unfriendly and cumbersome.
@vgalka-sl
As regarding to nullable-bool mentioned in #316, I think it would fit great into this model.
I will introduce my point of view concerning boolean options a.k.a (Flag/switch).
The boolean option is a flag (switch). It is a stand-alone key, whose presence or absence in the commandline provides information to the application.
The flag is an argument whose presence alone is enough to convey information to the application.
A good example is the frequently-used “-v” or "--verbose" argument.
The switch --feature or --no-feature may be used as a parameter for a method like this:
void EnableFeature(bool feature)
{
if (feature) //flag is passed in commandline --feature
EnableFeatureA
else //flag isn't passed in commandline
DisableFeatureA
//is there a third action for null?! Raise the Flag or down :)
// With option --no-feature we inverse the logic of if-then-else
// no-feature = (feature==false)
}
Two value true /false is enough to control the logic of enabling/disabling a feature, null may cause confusion.
Also --feature or --no-feature may be used and defined as an exclusive option.
I will provide two standard that handle Boolean options (flags/switch)
Handling boolean (flag) options
Flag options—set a variable to true or false when a particular option is seen—are quite common. optparse supports them with two separate actions, store_true and store_false. For example, you might have a verbose flag that is turned on with -v and off with -q:
5- Utilities with many flags generally show all of the individual flags (that do not take option-arguments) grouped, as in:
utility_name [-abcDxyz][-p arg][operand]
I think it could be extremely comfortable for all, if the library automatically supported this --no syntax for bool options.
It's a good point, but we should take into account how to be shown to the user in the help with short and longname.
There are two camps here:
I believe it's easy to satisfy both camps by adding an option to set --mybool=false just like you might set --myint=5. This can be done without modifying the existing behaviour, where --mybool on its own still indicates that value should be true.
Advantages:
Disadvantages:
--mybool=false will no longer be able to do that.I'd like to emphasize advantage 2. A couple of use cases for it, both of which I've encountered, and one of which I'm dealing with now:
--use_bar_for_foo, defaulting to false. After testing, they email all users, say "We're going to start using bar by default in a week, because it saves us money. It doesn't work in 5% of cases, so if you need to maintain the old behaviour, add --use_bar_for_foo=false to your commandlines now." A week later, they change the default value.I'm not saying either of these is impossible using this library as-is, but being able to set booleans to false is a clean solution to both of them.
[Option ( 'i', "IsRegexSearch", Required = false, Default = true, HelpText = "<edit>" )] public bool IsRegexSearch { get; set; }
@gaston-e-nusimovich, this does nothing as a flag, since there's currently no way to set it to false. That's part of what's being discussed here.
Is there any update on this issue?
I want to be able to set a boolean from the command line (to false) like this (or similar):
--test-option=false
[Option("test-option", Required = false, Default = true, HelpText = "Test option")]
public bool TestOption { get; set; }
--no-test-option does not get recognized as a valid command line switch either. Defining TestOption again with a different Option header obviously does not compile due to a variable re-definition. Is there really no other way to disable a boolean besides making it nullable?
[Option("test-option", Required = false, Default = true, HelpText = "Test option")]
public bool? TestOption { get; set; }
This should be possible in a mature library but it's alright. The nullable work-around works after all.
This works as expected if the user types -x or --option-x:
C#
[Option('x', "option-x", Required = false, Default = false]
public bool X { get; set; }
[Value(0)]
public IEnumerable<string> Values { get; set; }
But if the user types --option-x=false, then Options.X is true and Options.Values contains "false"!
General expectations for boolean options:
--option-x : X == true
--option-x=true : X == true
--option-x=false : X == false
--option-x=foo : parser error
I've gone for the nullable approach so far.
What is really disappointing is that the library chose to treat bool options as flag, even though the API and the user explicitly states otherwise (e.g. DefaultValue=true, --my-option=false, etc) but does not throw an exception to signal that something is wrong.
IMHO From the moment a bool option has a default value different than false, it should throw an exception. At the very least it would have stopped me from having the nasty surprise to discover that my command line options are broken weeks after writing the code.
Nullable option initially true
[Option ( 'i', "IsRegexSearch", Required = false, Default =(bool) true, HelpText = "<edit>" )]
public bool? IsRegexSearch
{ get; set; }
//argument: -i false
-i true
Closed for age.
Most helpful comment
@nemec
I'm sure there are cases where you want the boolean to be default True, and you want to give the user the ability to set it to False.