D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5042 - format("%s") of struct without toString
Summary: format("%s") of struct without toString
Status: RESOLVED DUPLICATE of issue 6595
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: Andrei Alexandrescu
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2010-10-11 15:18 UTC by bearophile_hugs
Modified: 2012-04-24 19:07 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-10-11 15:18:36 UTC
Given a plain struct like Foo, the to!string creates a good enough textual representation of it:


import std.conv: to;
struct Foo { int x; }
void main() {
    assert(to!string(Foo(1)) == "Foo(1)");
}



A nomal writefln("%s") just prints "Foo":


import std.stdio: writeln, writefln;
struct Foo { int x; }
void main() {
    writeln(Foo(1)); // ==> Foo
    writefln("%s", Foo(1)); // ==> Foo
}



But the format("%s") doesn't work:


import std.string: format;
struct Foo { int x; }
void main() {
    assert(format("%s", Foo(1)) == "Foo(1)");
}


DMD 2.049 gives the error:
std.format.FormatError: std.format Can't convert test.Point to string: "string toString()" not defined


I expect this format("%s") to return "Foo(1)" or "Foo" (I prefer "Foo(1)").
Comment 1 SomeDude 2012-04-22 09:13:12 UTC
I don't know if the bug is that std.string.format doesn't work on everything or if it's the sketchy documentation, "Format arguments into a string.", which implies that it should work on everything without further explanations.
Comment 2 Kenji Hara 2012-04-22 17:36:58 UTC

*** This issue has been marked as a duplicate of issue 6595 ***
Comment 3 bearophile_hugs 2012-04-24 18:42:50 UTC
In dmd 2.060alpha:


import std.stdio: writeln, writefln;
import std.string: format;
struct Foo { int x; }
void main() {
    writeln(Foo(1)); // ==> Foo(1)
    writefln("%s", Foo(1)); // ==> Foo(1)
    writeln(format("%s", Foo(1))); // run-time error
}


I see this error still:

Foo(1)
Foo(1)
std.format.FormatException@std\format.d(4749): Can't convert test.Foo to string: "string toString()" not defined


If it's isn't a problem in just my DMD, then I'll reopen this issue...
Comment 4 Kenji Hara 2012-04-24 18:56:37 UTC
(In reply to comment #3)
> In dmd 2.060alpha:
> 
[snip]
> 
> If it's isn't a problem in just my DMD, then I'll reopen this issue...

std.string.format function only support TypeInfo based formatting.
Then it never supports raw field based, and alias this based formatting.

As discussed here:
https://github.com/D-Programming-Language/phobos/pull/231

For the backward compatibility, we cannot change the implementation of std.string.format function. Instead, in 2.060head, we add a xformat function that uses std.format.formattedWrite function as the implementation.

After all, you should use std.string.xformat instead of std.string.format in 2.060 and later.
Comment 5 bearophile_hugs 2012-04-24 19:07:34 UTC
(In reply to comment #4)

> After all, you should use std.string.xformat instead of std.string.format in
> 2.060 and later.

Thank you Hara, this works:

import std.stdio: writeln, writefln;
import std.string: xformat;
struct Foo { int x; }
void main() {
    writeln(Foo(1)); // ==> Foo(1)
    writefln("%s", Foo(1)); // ==> Foo(1)
    writeln(xformat("%s", Foo(1))); // ==> Foo(1)
}