Skip to content

Rant: MultipleValues considered harmful #2031

@intgr

Description

@intgr

Sorry, but a rant here... I accept that other people might have a different view on this, but let me make my case.

I've only been scratching the surface of clap, both as CLI application developer and hacking clap itself. And I'm already losing count of the number of times I've been confused by the distinction between MultipleValues and MultipleOccurrences.

As positional arg

I was trying to test a positional argument (with TrailingVarArg in #1793) and figure out, which of the two settings is correct. It turns out, both are needed for it to work correctly. With just one or the other set, it results in surprising and non-useful behavior. So I think either it should be an error to use positional args with one Multiple* flag without the other, or the behavior should be changed to only need one.

Code

    App::new("Alter Ego: run desktop applications under a different local user")
        .setting(AppSettings::TrailingVarArg)
        .arg(
            Arg::new("command")
                .about("Command name and arguments to run (default: user shell)")
                .multiple_*(true) // multiple_values/multiple_occurrences
                .value_hint(ValueHint::CommandWithArguments),

Current actual behavior

  • Using MultipleOccurrences: Found argument 'asd' which wasn't expected, or isn't valid in this context
  • Using MultipleValues: The argument '...' was provided more than once, but cannot be used multiple times

As named arg

As for named options, MultipleValues might serve a purpose, but I think it's confusing for users of clap-based applications as well. I can't name a single common Unix utility from the top of my head that would accept multiple values after some --option switch. And there isn't support for such behavior in shell completion either, which is the topic of my PR #1793.

Indeed I'm not the first person working on clap to be confused by this duality; zsh.rs has this:

        // @TODO @soundness should probably be either multiple occurrences or multiple values and
        // not both
        let multiple = if o.is_set(ArgSettings::MultipleOccurrences)
            || o.is_set(ArgSettings::MultipleValues)

I can't help but feel that the MultipleValues feature is a mistake. Or maybe it is useful in some edge case, but should be discouraged and not exist as a prominent Arg::multiple_values() method, and should not be part of Arg::multiple().

Additional context

Using clap latest master branch, commit dc363d0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions