Bug 13480 – Input range formatting should not format as "elements"
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-16T03:58:00Z
Last change time
2014-09-16T09:44:55Z
Assigned to
nobody
Creator
jakobovrum
Comments
Comment #0 by jakobovrum — 2014-09-16T03:58:21Z
Consider the following (output in comments):
---
import std.algorithm;
import std.stdio;
import std.string;
void main()
{
auto ror = ["one", "two", "three"];
writefln("%(%s%| %)", [1, 2, 3]); // 1 2 3
writefln("%(%s%| %)", "abc"); // 'a' 'b' 'c'
writefln("%(%s%|, %)", ror); // "one", "two", "three"
writefln("%s", ror.joiner(", ")); // one, two, three
writefln("%s", ror); // ["one", "two", "three"]
}
---
writefln statement #2 and #3 don't make any sense. Formatting characters and strings using the element markup style (`formatElement`), which forces single and double quotes around the character or string respectively, defeats the purpose of range-based formatting, which allows you to customize the fluff around each element.
Not adding quotes is the more general solution; when quotes are desired, they can be explicitly added like so: `%("%s"%|, %)`.
This behaviour neuters range-based formatting severely: std.format deals with creating text, and strings and characters are the most basic units of text, yet this behaviour renders range-based formatting unusable when quotes are not desired (which is probably the vast majority of cases).
Comment #1 by k.hara.pg — 2014-09-16T08:02:31Z
(In reply to Jakob Ovrum from comment #0)
> writefln statement #2 and #3 don't make any sense. Formatting characters and
> strings using the element markup style (`formatElement`), which forces
> single and double quotes around the character or string respectively,
> defeats the purpose of range-based formatting, which allows you to customize
> the fluff around each element.
If you want to stop automatic element quoting, you can use "%-(".
void main()
{
auto ror = ["one", "two", "three"];
writefln("%-(%s%| %)", [1, 2, 3]); // 1 2 3
writefln("%-(%s%| %)", "abc"); // a b c
writefln("%-(%s%|, %)", ror); // one, two, three
}
It's documented in: http://dlang.org/phobos/std_format
> Inside a compound format specifier, strings and characters are escaped
> automatically. To avoid this behavior, add '-' flag to "%(".
Comment #2 by jakobovrum — 2014-09-16T08:11:50Z
(In reply to Kenji Hara from comment #1)
> If you want to stop automatic element quoting, you can use "%-(".
>
> void main()
> {
> auto ror = ["one", "two", "three"];
> writefln("%-(%s%| %)", [1, 2, 3]); // 1 2 3
> writefln("%-(%s%| %)", "abc"); // a b c
> writefln("%-(%s%|, %)", ror); // one, two, three
> }
>
> It's documented in: http://dlang.org/phobos/std_format
>
> > Inside a compound format specifier, strings and characters are escaped
> > automatically. To avoid this behavior, add '-' flag to "%(".
Thanks, nice to know it's possible to work around.
However, I don't think this flag should need to exist.
If strings were simply not quoted, one could get quoting by doing the much more intuitive explicit quoting: `%("%s"%|, %)`. Using '-' is just a hack - it has nothing to do with left-justification and thus the reader has to look it up to know what it does. We should follow the principle of least surprise here, by formatting the string as-is unless quoting is added by the user.
(changed severity to enhancement)
Comment #3 by k.hara.pg — 2014-09-16T09:42:56Z
(In reply to Jakob Ovrum from comment #2)
> Thanks, nice to know it's possible to work around.
>
> However, I don't think this flag should need to exist.
>
> If strings were simply not quoted, one could get quoting by doing the much
> more intuitive explicit quoting: `%("%s"%|, %)`. Using '-' is just a hack -
> it has nothing to do with left-justification and thus the reader has to look
> it up to know what it does. We should follow the principle of least surprise
> here, by formatting the string as-is unless quoting is added by the user.
Handmade quoting is not enough for strings which contain double-quote character.
See:
import std.stdio;
void main() {
string s = `Hello "D" world!`;
writefln("[%(%s%)]", [s]);
}
will output:
["Hello \"D\" world!"]
By design, std.format.formatValue functions stringize values by using unformattable representation with unformatValue functions by default.
That's the reason why automatic quoting is done by default.
Comment #4 by jakobovrum — 2014-09-16T09:44:55Z
(In reply to Kenji Hara from comment #3)
> (In reply to Jakob Ovrum from comment #2)
> > Thanks, nice to know it's possible to work around.
> >
> > However, I don't think this flag should need to exist.
> >
> > If strings were simply not quoted, one could get quoting by doing the much
> > more intuitive explicit quoting: `%("%s"%|, %)`. Using '-' is just a hack -
> > it has nothing to do with left-justification and thus the reader has to look
> > it up to know what it does. We should follow the principle of least surprise
> > here, by formatting the string as-is unless quoting is added by the user.
>
> Handmade quoting is not enough for strings which contain double-quote
> character.
> See:
>
> import std.stdio;
> void main() {
> string s = `Hello "D" world!`;
> writefln("[%(%s%)]", [s]);
> }
>
> will output:
> ["Hello \"D\" world!"]
>
> By design, std.format.formatValue functions stringize values by using
> unformattable representation with unformatValue functions by default.
> That's the reason why automatic quoting is done by default.
OK, good point. Thanks for explaining!