Bug 10814 – Formatting string-based enum prints its name instead of its value
Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-08-13T02:17:00Z
Last change time
2014-03-31T04:56:35Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2013-08-13T02:17:00Z
-----
import std.stdio;
enum Type : string
{
button = "type::button",
}
void main()
{
writeln(Type.button);
writefln("%s", Type.button);
writeln(cast(string)Type.button);
}
-----
Prints:
button
button
type::button
It's really strange that we have to cast an enum just to retrieve the actual value.
Note for example what happens when you use '%d' on an enum:
-----
import std.stdio;
enum Type : int
{
button = 1,
}
void main()
{
writefln("%s", Type.button);
writefln("%d", Type.button);
}
-----
Prints:
button
1
However you can't use this trick for string enums since there's no equivalent format specifier to retrieve an actual string.
There should be a way to always format the actual value of an enum in writef/format calls. "%s" might try to do the convenient thing by default, so maybe a new format specifier would be required? E.g. "%e" for enum values.
Alternatively one would write a helper template, e.g. toBaseValue(enumVal), which would return the base type value of an enum:
-----
import std.stdio;
enum Type : int
{
button = 1,
}
enum Type2 : string
{
button = "ttk::button",
}
template EnumBaseType(E) if (is(E == enum))
{
static if (is(E B == enum))
alias EnumBaseType = B;
}
T toBaseType(E, T = EnumBaseType!E)(E val)
{
return cast(T)val;
}
void main()
{
writefln("%s %s", Type.button.toBaseType, Type2.button.toBaseType);
}
-----
Prints:
1 ttk::button
Comment #2 by andrej.mitrovich — 2013-08-13T03:56:19Z
(In reply to comment #1)
> Another Workaround:
> writeln("" ~ Type.button);
Well, that might even allocate. I thought slicing could work too, but the following doesn't compile:
writeln(Type.button[]);
Error: template std.stdio.writeln(T...)(T args) cannot deduce template function from argument types !()(Type)
Comment #3 by monarchdodra — 2014-03-31T03:42:37Z
(In reply to comment #0)
> Alternatively one would write a helper template, e.g. toBaseValue(enumVal),
> which would return the base type value of an enum:
https://d.puremagic.com/issues/show_bug.cgi?id=11571
In particular, it deals with your specific problem.
Comment #4 by andrej.mitrovich — 2014-03-31T04:56:35Z
Filing this as invalid since it would be a breaking change. Workarounds exist and are easy enough to use, so I'm closing this.