Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support boolean argument with the form like '--enable-hack=true/false' #313

Open
rtgiskard opened this issue Dec 8, 2023 · 3 comments
Open

Comments

@rtgiskard
Copy link

This explicit switch can be useful when worked with config file.

Settings from argument generally take more priority over config file.
When it's not given explicitly via argument, the config file takes over.

For boolean argument, provide the argument means switch true/false, but just 1 state.
If the argument default is false, and setting in config file is true, Once I want to turn off the switch,
I have to change the config file.

For example, a case like this:

  • a switch --enable-hack set to true or false in config file.
  • an argument --enable-hack with default set to 'false' is given

If I want to enable the hack, I can pass arg --enable-hack, then the setting in config file will be ignored.
But once I want to disable the hack temporary, I have to change the config file as no argument provided
means using config file. Or I can add another arg --disable-hack, and then pass the argument to explicitly
disable the hack, which does not seem to be good.

It would be better if a boolean argument can also accept the form of --enable-hack=true/false

@wanjiadenghuo111
Copy link

wanjiadenghuo111 commented Dec 8, 2023 via email

@rtgiskard rtgiskard changed the title support bool args with the form like '--enable-hack=true' Support boolean argument with the form like '--enable-hack=true/false' Dec 8, 2023
@p-ranav
Copy link
Owner

p-ranav commented Dec 8, 2023

In the current library, this can be done by writing a custom action for each type of "true" "false" string that you want handled.

int main(int argc, char *argv[])
{
    argparse::ArgumentParser program("program_name");

    program.set_assign_chars("=:");

    program.add_argument("--enable-hack")
        .default_value(false)
        .action([](const auto& str) {
            return (str == "true");
        });

    try {
        program.parse_args(argc, argv);
    } catch (const std::runtime_error &err) {
        std::cerr << "argparse failed with:" << err.what() << "\n";
        std::cerr << program;
        return 1;
    }

    std::cout << "Hack enabled: " << std::boolalpha << program.get<bool>("--enable-hack") << "\n";

    return 0;
}
foo:bar $ ./main
Hack enabled: false
foo:bar $ ./main --enable-hack=true
Hack enabled: true

@rtgiskard
Copy link
Author

rtgiskard commented Dec 9, 2023

Just update to the latest version 3.0, find that this behavior may not be the desired one:

For a piece of code like this:

  program.set_assign_chars("=");
  program.add_argument("--enable-hack")
      .default_value(false)
      .action([](const auto &str) { return (str == "true"); });

  program.add_argument("--enable-a").flag();

--enable-hack true, --enable-hack=true seems to be equivalent, but --enable-hack will apply parser["--enable-hack"]==false, which is not desired. And the help message print as:

Optional arguments:
  -h, --help     shows help message and exits 
  -v, --version  prints version information and exits 
  --enable-hack  [nargs=0..1] [default: false]
  --enable-a

And for general boolean argument like this:

  program.set_assign_chars("=");

  program.add_argument("--enable-hack")
      .default_value(false)
      .implicit_value(true)
      .action([](const auto &str) { return (str == "true"); });

  program.add_argument("--enable-hack").flag()
      .action([](const auto &str) { return (str == "true"); });

--enable-hack=true will be treated as positional arguments, which is not desired either.

It would be better to have a native boolean argument to handle the flexible switch via --boolean-a=true or sth similar

let me see, is it possible to have a boolean argument defined like this:

  program.add_argument("--enable-hack").flag();

and support the following equivalent arguments:

  • --enable-hack
  • --enable-hack=trure
  • --enable-hack=on

and the opposite, like:

  • --enable-hack=false
  • --enable-hack=off

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

No branches or pull requests

3 participants