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
std.getopt: Add character-separated elements support for arrays and associative arrays #2049
Conversation
How does one "escape" the comma though? I'm thinking
Does this still work, or will it now create 4 users (instead of 2)? We could decide to "split on sep" only if the field appears once? But then I'd expect this:
Maybe it would be better to simply split on white? It's much easier to handle in terms of common usage (people know white is ambiguous), and breaks nothing. EG:
|
What would this produce? |
string[] users = ["Robertson,Paul", "Smith,John", "Bush,George W." ]; |
This is definitely a complicated issue. I'll wait for others to comment for suggestions. |
This is fine as is. We don't want to get into issues such as shell quoting etc. One fixed separator should be enough. Only question I have is - should be be |
I realize it's much easier to just hand wave the problem away, but this is a breaking change, and there is no "opt-out". We aren't getting into issues as such as "shell quoting", since these are already taken care of by said shell. Once "getopt" is invoked, it already has tokens. I think it is better to simply let the shell do the tokenizing (with/without escaping) on white. From there, given my example: As is, I can't give an LGTM. Another (maybe more involved?) solution, would be to make it possible to work with an opt-in specified separator? Something like: string[] s;
getopt(args,
"users", s, TokenSep(',')
); This would trigger the opt-in request for token separating. This is an off the top of my head idea. The fact you can specify the separator is a very good thing, IMO, as I've seen programs that separate on |
@andralex: I've tried to be consistent with the other options,
There is no need for this "TokenSep"-style API, we could just check whether |
So essentially we could split by whitespace by default, unless the user does things like: |
Essentially, I don't think we should be splitting on anything by default. Especially not whites, that's the shell's job. You'd break this trivial use case: ideally I'd think that having multiple tokens after an array/AA parameter should simply take them into account ( Having an opt-in separator would be ideal, but I really stress the "opt-in" part.
Hum... works for me as a workaround. It's not the "global" issue that I don't like, but potentially splitting two different fields that have nothing in common. But if we simply label it as a "limitation", I'm fine with it. |
Spec'ing this is getting out of hand. Probably it's best to just close it.
To make this a non-breaking change, we could just set the implicit separator to the empty string. I think it would be nice to accept this with a separator string (by default "" i.e. no multiple elements) with no escaping and no frills, and move on. If this is not to everybody liking let's close this. |
Sounds good to me.
It's to my liking. @AndrejMitrovic ? Seems easy enough to do, I think? |
@AndrejMitrovic let's convert this into a miraculous win! |
I don't think it's that easy. Consider this: import std.getopt;
void main()
{
string[] files;
auto args = (["program.name", "--files", "file1.txt", "file2.txt"]).dup;
getopt(args, "files", &files);
assert(files == ["file1.txt"]);
assert(args == ["program.name", "file2.txt"]);
} This would break with the proposed enhancement, which would assume "file2.txt" should be put into the |
Yeah... What I proposed would indeed be a change of behavior. Better to simply leave the current behavior as is. I'm fine with it. So all that's left is making a global |
Ok, so the supported set of features are: string[] files; // files gets "file1.txt" *only* (same behavior as old behavior)
auto args = (["program.name", "--files", "file1.txt", "file2.txt"]).dup; Ditto, old behavior: string[] files; // files gets ["file1.txt", "file2.txt"]
auto args = (["program.name", "--files", "file1.txt", "--files", "file2.txt"]).dup; New feature: arraySep = ",";
string[] files; // files gets ["file1.txt", "file2.txt"]
auto args = (["program.name", "--files=file1.txt,file2.txt"]).dup; |
Is that it? |
Sounds good to me! What about: arraySep = ",";
auto args = (["program.name", "--files=file1.txt,file2.txt"]).dup;
vs
auto args = (["program.name", "--files file1.txt,file2.txt"]).dup; Same behavior for both? |
auto args = (["program.name", "--files file1.txt,file2.txt"]).dup; That one will throw an exception thinking the entire second string is a switch (current behavior). Did you mean the following?: auto args = (["program.name", "--files", "file1.txt,file2.txt"]).dup; |
Yes. Same behavior for both? |
Yep. Updated pull request. |
|
||
if (arraySep == "") | ||
{ | ||
*receiver ~= to!(typeof((*receiver)[0]))(val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized I can use to!E here. Should I fix it up (since the tester is green)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
…s and associative arrays.
std.getopt: Add character-separated elements support for arrays and associative arrays
Awesome. |
I sure hope I got this right. I do love writing templates in D. :>
https://d.puremagic.com/issues/show_bug.cgi?id=5316