Two possibilities of fixing format problem, which is better?

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Oct 23 18:48:42 UTC 2019


On Wed, Oct 23, 2019 at 02:45:51PM +0000, berni44 via Digitalmars-d wrote:
> On Tuesday, 22 October 2019 at 17:12:53 UTC, H. S. Teoh wrote:
> > IMO, yes.  When you write "%20s" you're essentially saying "format
> > the next argument as a string with width 20". It's unexpected
> > behaviour for the width to suddenly apply to elements within the
> > object as opposed to the object itself.
> 
> While trying to implement this I came across a function called
> formatElement. Next to this there is a comment saying "undocumented
> because of deprecation". Does anyone know about this "deprecation" of
> formatElement?

git blame and git log --graph reveal that the "deprecation" came from
Phobos PR #2890. Perhaps start by looking there?  What I'd do is to
checkout Phobos just before that PR merge and then do a further git
blame / git log --graph to find when formatElement was changed before
that. Hopefully the history of changes will help you piece together what
exactly happened, and perhaps suggest some possible reasons why.


> It's used inside std.format, e.g. for formating ranges. And it appears
> in one public example, where it probably should not appear.
> 
> The reason I'm asking is, that I'd like to get the following unittest
> working:
> 
> unittest
> {
>     int[2] a = [-5, 345];
>     string t1 = format("[%10s] [%-10s]", a, a);
>     assert(t1 == "[ [-5, 345]] [[-5, 345] ]");
> }
> 
> So far I managed to do this, but now an other unittest pops up, namely:
> 
> formatTest( [cast(string)"hello"], `["hello"]` );
> 
> This is essentially, because the old implementation called
> formatElement, while the new one doesn't. Looking inside
> formatElement, this function formats the element not according to some
> %... parameter, but similar to how it would be presented as a litteral
> in source code.
> 
> Now I'm unsure, how to continue.

I don't know the entire story behind this, but what I know is this: in
certain cases, std.format was expected to format certain aggregates of
strings such that each string was quoted. One case is string[], where
the output was expected to be like this:

	["abc", "def", ... ]

rather than:

	[abc, def, ... ]

Why, I'm not really sure, but later on the '-' flag was added to the %s
specifier in order to get the second behaviour instead of the first
(i.e., "%-s instead of %s").  Obviously, when this was done whoever did
it wanted to maintain backward compatibility with the auto-quoting
behaviour, so the second behaviour is not default, but you have to
explicitly ask for it with the '-' flag.  This is why in certain
aggregate formats involving %(...%) I often find myself having to revise
it to %-(...%) instead, just so the strings will show up correctly in
the output.

I'd suggest you try to maintain backward compatibility with this special
case behaviour, if possible, so that existing codebases won't get a
nasty surprise (suddenly quoted strings are no longer quoted in the
output). AFAIK, this special-casing only applies to string elements;
other types should be free of such odd behaviours.

P.S. If it were up to me, I'd try to get rid of this awkward special
case, but then I'm not exactly sure how one would go about deprecating a
certain aspect of format strings, esp. since most older code use runtime
format strings, so you can't get any warning until runtime, which is
very bad for deprecations.


T

-- 
That's not a bug; that's a feature!


More information about the Digitalmars-d mailing list