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
number_of_values with and without Option is weird/bad #364
Comments
This is fine analysis. It is also mostly correct, so be all your code blessed by God of Computing. Amen. Small nit:
You did ask for it. You see, the very essence of A hint: you didn't really need to check the code on your own because we have this spectacular table which describes what methods structopt generates and when it does so.
|
invocation | result |
---|---|
app --foo a b |
Some(["a", "b"]) |
app --foo |
Some([]) |
app |
None |
That's about it. Yes, it kinda does stand out from other usages of Option
in structopt, but so does Vec
. I think this is a liable exception.
Changing it now - I mean, making Vec
required by default - would be a breaking change for the vast majority of our users, and it would be for little or no benefit. Even if we were to consider a major version bump, like some dude on twitter said - "Dozens of thousands lines of code won't rewrite themselves". I don't think it's a big burden for you to add required = true
where appropriate, is it?
P.S. There is a proposal which you may like, here. If you do, please, go there and give it some love (a comment or emoji). The more attention it gets, the more I am inclined to stop procrastinating and just fucking do it.
First of all I must apologize because my first message has been misinterpreted by GitHub's Markdown syntax and all the
Dear Lord Creepy Skeleton: I think I know something about clap that you don't 😅 My apologies, I don't want to sound like a smart ass! In fact From the doc:
In fact, with clap there are 3 ways to allow multiple values:
It works with either of these.
You can see in the example above that it works perfectly fine. It just won't allow to insert multiple time the same argument anymore:
It seems to me that in its current state structopt is neither consistent with its own rules neither with clap's ones:
Like you I'm interested in the history and I wouldn't want to break people's stuff. That is why I recommended to update the MAJOR if we would change this behavior. This is the case mentioned by the PR you mentioned:
But here I don't see any relation between "optional option with optional value" and "optional vec with maybe no value". These are all different things. Does changing the behavior with Vec would break the behavior of Option? In the case of Vec, someone who would really want to distinguish an empty set of value with no parameter provided at all, should probably do this instead:
Here I can clearly read:
So the question is: why it hasn't been done that way?? If I look at the PR of May 2019 (< 0.3.0), I read:
I'm puzzled because you can definitely specify the min_values nowadays with structopt. So I tested with the latest version they are probably using in the PR: 0.2.17 and I found out that it is actually very hard (maybe impossible?) to declare an
But that won't help you much because |
I think the misunderstandings come from my original post where the |
Nope, I believe I got it right from your first explanation. It did confused me at first, but I correctly derived your real meaning after some thought. The misunderstanding originates from somewhere else, and I assume I know where it's from.
You do, and I like smart 😎 ! Keep it going 👌. And I am not Lord, not yet; I am a humble servant whose talents are many and various, and whose work is superb and extraordinary. I'll be answering your points (as I figured them out) one by one because I seemingly have some mental issues with laying my thoughts out whenever I think about different things at once. A tittle is your point as I see it. Offtopic: I would really like to hear you opinion on clap-rs/clap#1682 , I highly suspect it would solve your use case charmingly. Multiple occurrences plus multiple values is not a good default for
|
invocation | result |
---|---|
app --foo a b | Some(["a", "b"]) |
app --foo | Some([]) |
app | None |
Option<Vec<T>>
is in use for distinguishing between "no option" and "option but no args". Changing it to requred = false
would be breaking and it would have little benefit for users (see the next section below).
So the question is: why it hasn't been done that way??
Well, if my after-the-fact flavor of mindreading is to be trusted, they just wanted it to look out-of-box, screw the consistency. We would need a time machine to figure for sure; do you have one?
Breaking changes are fine as long as we bump MAJOR version (0.4 in our case, but whatever). (Yes and... kind of not-yes)
It's not that easy.
You see, people are inert. Once they have written some code, they expect it to work until the Second Coming. This is also applicable to people's habits: if they got used to some API, they will also expect that the future versions will work similarly. And don't forget that the transition to a new backward incompatible version means rewriting tons of old code, the deed that worth the most generous reward.
Of course, it's not that bad. If people are promised some significant benefits - read features/bugfixes - they could overcome their sloth, lack of time, lack of enthusiasm (billion excuses exist). It means that the benefits must worth the effort required to perform the transition.
With all due respect, these changes you have proposed - despite that I mostly agree with them! - they bring almost no benefits for existing users. They are totally cosmetic and do not offer anything that couldn't be done with the current version. They would help newcomers though.
I'm not absolutely against it, no; I'm just afraid we will end up with two versions of structopt to maintain - one for old users and one for newcomers. In the light of upcoming clap_derive
(it does progress, mind you, as slow as it might be), I urge you to redirect you efforts there.
OK, @cecton can I call it a successful mindreading test?
So. I had to think about it because there are many points in this discussion. I will try to focus on the one that is actually the subject of the conversation: number_of_values with and without Option is weird/bad
So to refocus the discussion: do we want to change this behavior? From a personal point of view I don't need it. To be honest, I'm not even sure I would have seen this if I didn't have to parse a tuple. So I guess this is fine. What you propose in #1682 would work for me. From a general point of view:
No problem at all! Thanks :) So I guess we can close this ticket from my point of view. Even if nothing changed it is good to have a ticket that talk about it so someone who will bump into the same issue will know what's going on. If someone has a real practical use case where they need this to be consistent somehow, it's best to re-open this ticket and explain the use case (or open a new one but link this one). |
Before you read: if someone has a real practical use case where they need this to be consistent somehow, it's best to re-open this ticket and explain the use case (or open a new one but link this one).
There are 2 cases here that I find counter intuitive. The first one is when you use number_of_values with a Vec: it allows the user to not provide the parameter at all despite the field is not an Option. The second one is when you use number_of_values with an
Option<Vec>
: it allows the parameter to be passed with no value at all.According to the doc of clap,
number_of_values
:Therefore:
Option<Vec>
makes no sense. It shouldn't behave that way.Related to #349
Case 1
Code sample
Expected behavior
values
is required and is valid ONLY if 2 values are provided. Example:Or:
Actual behavior
values
is optional and is valid IF 2 values are provided OR the parameter is not used at all. Example:Or:
Or:
Case 2
Code sample
Expected behavior
values
is optional and is valid IF 2 values are provided OR the parameter is not used at all. Example:Or:
Or:
Actual behavior
values
is optional and is valid IF 2 values are provided OR 0 values are provided OR the parameter is not used at all. Example:Or:
Or:
Or:
Analyze
I checked both cases with cargo-expand to see what code is generated. And this is what I found:
Case 1
Case 2
Conclusion
I believe it would be best to change these behaviors to make it more intuitive but this will break everybody's code so I suggest to upgrade the MAJOR.
The text was updated successfully, but these errors were encountered: