Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
July 08, 2007 "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Hi, while trying to code/port some stuff heavily relying on enums, I asked myself, whether there is a nice and elegant way to actually get the name of an enum value as string. enum Funny { UNKNOWN, MAKES_ME_SMILE, LAUGHING_OUT_LOUD, ROLLING_ON_THE_FLOOR_LAUGHING } void main() { Funny joke = Funny.LAUGHING_OUT_LOUD; wrifeln("%s", toString(joke)); } should print "Funny.LAUGHING_OUT_LOUD". I could also live with "LAUGHING_OUT_LOUD". But keeping these two tables (string[] and enum) in sync requires some kind of preprocessor and D has none. How is that kind of problem solved in D WITHOUT keeping two tables? Many thanks and Best Regards Ingo Oeser |
July 08, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ingo Oeser | The topic of converting enums to strings has come up before.
IIRC, the problem is that enums tend to be used for one of two purposes: a collection of fixed constants, and bit fields/masks. While the former may be easy to do, the latter presents a problem... Especially when the values of different fields overlap.
Ingo Oeser wrote:
> Hi,
>
> while trying to code/port some stuff heavily relying on enums,
> I asked myself, whether there is a nice and elegant way
> to actually get the name of an enum value as string.
>
> enum Funny {
> UNKNOWN,
> MAKES_ME_SMILE,
> LAUGHING_OUT_LOUD,
> ROLLING_ON_THE_FLOOR_LAUGHING
> }
>
> void main()
> {
> Funny joke = Funny.LAUGHING_OUT_LOUD;
> wrifeln("%s", toString(joke));
> }
>
> should print "Funny.LAUGHING_OUT_LOUD". I could also
> live with "LAUGHING_OUT_LOUD". But keeping these two tables
> (string[] and enum) in sync requires some kind of preprocessor and D has none.
>
> How is that kind of problem solved in D WITHOUT keeping two tables?
>
> Many thanks and Best Regards
>
> Ingo Oeser
>
|
July 09, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ingo Oeser | "Ingo Oeser" <ioe-news@rameria.de> wrote in message news:f6r5mi$2q7n$1@digitalmars.com... > > How is that kind of problem solved in D WITHOUT > keeping two tables? > Unfortunately the language also doesn't provide any way of querying information about an enum other than its min, max, and default values.. it would be nice, given a named enum, to get a .tupleof the valid values, where each item in the tuple would be an alias to one of the valid enum values. Furthermore, EnumValue.stringof would have to give a string representation of the actual enum value, rather than a string of the type as it does now (I think .stringof is still not 100% finished anyway..). With those two abilities, generating some kind of lookup table at compile-time would be very easy indeed. But of course as Jason pointed out, one issue is with flag enums. C# kind of solves this by allowing you to put a "Flags()" attribute or so on the enum, which gives the runtime a hint as to how to stringize a given enum value (it comes out as something like "Blah.A, Blah.B, Blah.C" if you have multiple values or'ed together). I'd even go so far as to say that the use of an enum as a simple list of constants and the use of an enum as a list of flags is divergent enough to warrant a new language construct -- i.e. "flags Blah { A, B, C }". You wouldn't have to manually specify the values as you have to with flag enums, and it makes sense to Or together multiple flag values; it usually doesn't make sense to Or together multiple values of a "constants" enum. |
July 09, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | This would be nice: Funny.tupleof should return a Tuple of values, like: "0 1 2 3" Funny.names should return the names like: UNKNOWN, MAKES_ME_SMILE, ... I guess with compile-time reflection we can also expect features like that. Some time ago I was trying to do serialization, but getting the name of a member variable from a struct is not possible: struct Foo { int x; int y; }; Foo foo; writefln(foo.whatever[0]) should return "x"; Atm there is no builtin way to do this. Daniel |
July 10, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel919 | Daniel919 wrote:
> This would be nice:
> Funny.tupleof should return a Tuple of values, like: "0 1 2 3"
> Funny.names should return the names like: UNKNOWN, MAKES_ME_SMILE, ...
Doing it with tuples is only slightly useful, since there can be gaps in enums.
That's why I would like to have the names of the enums members, only.
Best Regards
Ingo Oeser
|
July 10, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > Furthermore, EnumValue.stringof would have to give a string representation of the actual enum value, rather than a string of the type as it does now That behavior would be perfect! This is also much better that min/max, since enums can contain holes. Enums are just a set of valid symbols with defined ordering within a scope. > (I think .stringof is still not 100% finished anyway..). With those two abilities, generating some kind of lookup table at compile-time would be very easy indeed. And is very much needed. Just look how often that kind of stuff is implemented! Maybe we can have the best of both worlds and just get a string[enum foo] from any named enum, where we can iterate either through the keys or through the values. > But of course as Jason pointed out, one issue is with flag enums. They are nothing else but additional values for me. Consider: enum Foo { bar = 1, baz = 2, boo = 4, all = bar | baz | boo, } Foo.all is just an additional valid value. The way it is composed is nothing else but an implementation detail, which can change. > I'd even go so far as to say that the > use of an enum as a simple list of constants and the use of an enum as a > list of flags is divergent enough to warrant a new language construct > i.e. "flags Yes, that is a completely new semantic, which is called "set" :-) Ok, that is actually a "set of enum values" which might be an interesting specialisation for the set template :-) We don't have that semantic now. But we have enums and they miss a useful method. That is my point. Maybe I should forward that thread to the "D" newsgroup? Best Regards Ingo Oeser |
July 10, 2007 Re: "toString(enum.value)" How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ingo Oeser | "Ingo Oeser" <ioe-news@rameria.de> wrote in message news:f70i4s$2o0d$1@digitalmars.com... > > Doing it with tuples is only slightly useful, since there can be gaps in enums. > Not if the tuple was a tuple of aliases to the enum members. For example, something like this: enum X { A, B, C = 6 } alias X.A _A; alias X.B _B; alias X.C _C; template Tuple(T...) { alias T Tuple; } alias Tuple!(_A, _B, _C) XTupleof; .. foreach(val; XTupleof) writefln(val); this shows "0 1 6". This of course is just the manual implementation of what the compiler could do for us. Basically it'd become foreach(val; X.tupleof) writefln(val); and the tuple would be aliases to each value. Then you could do .stringof on val and get the name. And from there, it's a very short jump to generating the actual table. Or, as you said, if the compiler could just give us a .namesof or something like that, we wouldn't have to do anything at all ;) |
Copyright © 1999-2021 by the D Language Foundation