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 #1 by rswhite4 — 2013-08-13T02:39:18Z
Another Workaround: ---- import std.stdio; enum Type : string { button = "type::button", } void main() { writeln("" ~ Type.button); } ---- prints: type::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.