From: Scott Thompson Date: 2003-08-15T01:13:01+09:00 Subject: Re: Exposing C "enums" through extensions > An interesting solution. > > I prefer to use instances of a particlar class instead, e.g.: > > MyEnum = Struct.new(:name, :value) > class MyEnum > def to_s > return name() > end > end > > THIN_LINE = MyEnum.new("THIN" , 0) > THICK_LINE = MyEnum.new("THICK" , 1) > MONSTER_LINE = MyEnum.new("MONSTER" , 2) > > Then I can write something like: > > case line_style > when THIN_LINE then ... > when THICK_LINE then ... > when MONSTER_LINE then ... > end This is a common idiom in Java. It's described pretty nicely in the book Effective Java Programming Language Guide (a book which I greatly enjoyed in spite of the fact I have written very, very little Java). It's a nice choice in that environment because it plays well with Java's stronger typing system. That particular argument don't make much sense for Ruby, but by no means does that invalidate the technique. Unfortunately it also doesn't really solve the problem I was trying to avoid. The user of this API can still easily replace THIN_LINE with a completely different value. Granted they will receive a warning, and probably deserve what they get, but that's the thing I was trying to avoid. Something about non-constant constant's just rubs me the wrong way... too many years of C++ conditioning I guess. In the end, I decided that I can't protect the user from themselves all the time. Besides it is much more important to make sure that the API for the extension is Ruby (and not some bizzarre imitation of Ruby). Ruby allows you to replace constants, for better or worse, so I made the enum's into Fixnum constants. If anyone wants to change my mind, however, I'm open to other suggestions. Scott