From: Paul Brannan Date: 2003-08-14T23:25:57+09:00 Subject: Re: Exposing C "enums" through extensions On Wed, Aug 13, 2003 at 08:53:53PM +0900, Brian Candler wrote: > Nor would I; but if it were a concern you could use symbols instead, and a > hash to map to the correct constant value. > > class MyClass > LINES = { > :thin => 1, > :thick => 2, > :monster => 3, > } > def self.set_line_size(x) > @@line_size = LINES[x] || (raise "Bad value") > end > end > MyClass.set_line_size(:thick) 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 Or something like: puts THIN_LINE #=> "THIN" It's also possible to add singleton methods to each of these objects to avoid case/when. I've written a few classes to help me generate these type of enums in Ruby code and in extensions: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/rubycollections/rubycollections/rbc/enum.rb?rev=1.7&content-type=text/vnd.viewcvs-markup http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/excruby/excruby/excruby/enum_wrapper.hpp?rev=1.2&content-type=text/vnd.viewcvs-markup The latter has no sample code, but in my extensions I write something like: Exc_Ruby::Enum_Wrapper line_style; extern "C" void Init_extension() { line_style .initialize(rb_cObject, "Line_Style") .define_value("THIN_LINE" , THIN_LINE) .define_value("THICK_LINE" , THICK_LINE) .define_value("MONSTER_LINE" , MONSTER_LINE) } And on days when I'm not in the mood to deal with something this heavyweight, I can always cheat a little and just use instances of Class instead of instances of a particular enum type: class THIN_LINE ; end class THICK_LINE ; end class MONSTER_LINE ; end Paul