I want to have parameter values parsed into u64s, but they get special treatment instead. Apparently a u64 captures all remaining parameters and is set to the number of remaining parameters? How is that useful if the values aren't accessible? Wouldn't it make more sense for users to just use a Vec<String> here and call len() when they want the number of parameters?
That's a very common pattern. You find it a lot with verbose option. -v for verbose, -vv for very verbose, -vvv for extremely verbose. That would be inconvenient to have to call .len() on a vector.
If you want a u64, just do that:
#[structopt(short = "i", parse(try_from_str))]
integer: u64,
Ah, it wasn't clear to me from the documentation that "number of params" means the number of repetitions of that parameter, rather than the number of remaining parameters. Maybe that could be clarified.
And does it really make sense for it to be a u64? Why not a u8 or u16? Any command-line interface that expects the user to repeat a parameter more than 255 times seems like it must be poorly designed.
Anyway, thanks for structopt! I like it very much.
That's a u64 because the corresponding method in clap returns a u64.
I reopen the issue for the documentation clarification. I'll do it when I'll have the time. Feel free to open a PR if you are inspired.
Thanks for the feedback, that's always motivating to know that what we do is useful.
First thanks for structopt! I am new to it but I like it already.
When I read the doc I was also confused by the special handling of u64, at first glance the doc and examples seems not show how one can parse an integer parameter larger than max of u32 (if one really want to input a parameter larger than 2^32), as u64 is special for repetitions of the used arguments. I searched the issues and luckily I found this one, I'm glad I'm clear after reading the issue.
Maybe such info can be added to doc:
That's a very common pattern. You find it a lot with verbose option. -v for verbose, -vv for very verbose, -vvv for extremely verbose. That would be inconvenient to have to call .len() on a vector.
If you want a u64, just do that:
#[structopt(short = "i", parse(try_from_str))]
integer: u64,
Looks like that's not yet clear enough. I'll try to improve that.
Wowwww this just bit me so hard. Considering that this is treated specially and switching from a u64 to a u32 completely changes the semantics of the command line parser i sincerely wish that you鈥檇 remove this, as it definitely violates the principle of least surprise in multiple ways, etc.
This is not a user friendly feature at all.
For something that drastically modifies the behavior like this it should definitely be typed, like adding a thin type wrapper like Repetition(u64).
Also repurposing an (arbitrary) type to do something like reputation of arguments, which quite frankly is not common at all (I鈥檝e never done this and I鈥檝e written I don鈥檛 know how many command line tools using this crate at this point), and which is very likely only ever used with something like verbosity (if it鈥檚 used at all) just seems odd.
If the underlying crate is to blame there is no reason to repeat that mistake, and is easily rectified by a type wrapper, etc.
I agree. I've written 18 tools using structopt and none of them count repeated arguments. Also I can't remember the last time I used repeated arguments in any command. A type wrapper or an attribute would work just as well and avoid this pitfall.
This was rather surprising, given that a field with the type u32 works the way you'd expect, while switching to u64 suddenly doesn't.
It's feels rather unintuitive. A solution using Repetition(u64) as suggested by m4b would probably be better.
I, too, wasted time because of this. It's incredibly surprising, and I skipped right past it in the documentation because I really wouldn't have expected this behavior. I also recommend making u64 work as if it was parse(try_from_str) by default. To enable the functionality it currently has, you might consider recognizing a new field in variant attributes (say parse(multiple)) that works for any unsigned integer type. An alternative, as already proposed, is to recognize a custom type, say Repetition, but that would be the only type exported from StructOpt and again feels like an odd special case.
That will be parse(from_occurrences) and I've planned to do that for the 0.2. It will do a From::from(m.occurrences_of("name")) by default.
I can't find the time to do that, but I hope to do it soon.
@TeXitoi No worries! I find value in structopt, and it was a breeze to implement, so I went ahead and submitted a PR (https://github.com/TeXitoi/structopt/pull/48). I named it parse(multiple) as I hadn't seen your comment. Happy to rename it. It currently uses as to convert between integer types. From<u64> isn't implemented for any of the unsigned integer types except u64 and the unstable u128, so it doesn't seem like the right way to go.
Isn't using u64 for counting -vs an overkill on 32-bit platforms? Why not usize.
Anyway special-casing u64 here feels like special-casing std::vector<bool> in C++ - trading general consistency for little immediate use case.
I see this is already being addressed.
Most helpful comment
Wowwww this just bit me so hard. Considering that this is treated specially and switching from a u64 to a u32 completely changes the semantics of the command line parser i sincerely wish that you鈥檇 remove this, as it definitely violates the principle of least surprise in multiple ways, etc.
This is not a user friendly feature at all.
For something that drastically modifies the behavior like this it should definitely be typed, like adding a thin type wrapper like Repetition(u64).
Also repurposing an (arbitrary) type to do something like reputation of arguments, which quite frankly is not common at all (I鈥檝e never done this and I鈥檝e written I don鈥檛 know how many command line tools using this crate at this point), and which is very likely only ever used with something like verbosity (if it鈥檚 used at all) just seems odd.
If the underlying crate is to blame there is no reason to repeat that mistake, and is easily rectified by a type wrapper, etc.