> 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