From: Kedar Mhaswade Date: 2011-05-20T23:35:09+09:00 Subject: Reasonable attempt to do type-safe enum for Ruby? Perhaps this has been tried before. But I didn't find it. Google searches showed many different ways to implement an "enum" data type for Ruby. Searching on forum suggested using hashes, arrays and Struct. But none of them seemed type-safe to me. So, I went ahead and did something like below, for an enum named GenericState which represents a "state" of some kind. Please comment on this approach. # An enum kind of model. No persistent equivalent. # I still don't know the correct way of doing enums in Ruby! class GenericState attr_reader :state def initialize(s) @state = s end def to_s @state.to_s end ACCEPTED = GenericState.new(:accepted) EXPIRED = GenericState.new(:expired) IGNORED = GenericState.new(:ignored) REJECTED = GenericState.new(:rejected) SENT = GenericState.new(:sent) UNSURE = GenericState.new(:unsure) STATES = [ACCEPTED, EXPIRED, IGNORED, REJECTED, SENT, UNSURE] class << self include Enumerable def each(&block) STATES.each(&block) end alias all entries end # convenience methods def one_of_my_predicates?(meth) # meth is a symbol $1 if meth =~ /(.+)\?$/ && STATES.any?{|ss| ss.to_s == $1} end def run_predicate(method_name) method_name == to_s end def method_missing(meth, *args, &block) matched = one_of_my_predicates?(meth) if matched run_predicate(matched) else super end end end The method_missing protocol does not have to be implemented, but it facilitates more readable usage as indicated below. #usage puts GenericState.any? {|x| x == GenericState::SENT} # => true puts GenericState.all # => An array of all GenericState objects! s1 = GenericState::SENT s2 = GenericState::ACCEPTED s3 = GenericState::ACCEPTED puts s1 == s2 # => false puts s3 == s2 # => true puts s2.object_id; puts s3.object_id #=> they are the same objects puts "Does s1 imply sent? : #{s1.sent?}" # => true puts "Does s3 imply accepted? : #{s3.accepted?}" # => true puts s1.to_s #=> "sent" Best Regards, Kedar -- Posted via http://www.ruby-forum.com/.