From: James B Crigler Date: 2004-07-07T03:17:38+09:00 Subject: Enumeration (Ala Pascal, C, Ada) I put together the code that follows in an attempt to emulate (in a crude way) the "enumeration" types of Ada, C, Pascal, etc. The two classes reside in the same file and attempt to solve a problem I had with a process management system I use: The reports --- a separate file for each change --- list the status of the particular change. I wanted to be able to go through the reports and list all the changes for which the status is "less than" (or greater than or no bigger than or ...) some given status IN TERMS OF THE CHANGE DOCUMENT'S LIFE CYCLE, where statuses are not in alphabetical order. (This is a facility that the change management system itself does not provide.) The code works within the constraints within which it works. ("I'll take tautologies for 10, Alex!") I typically use it for composing command-line queries. E.g., if the possible states of a change doc are "CUT", "INSERT", "CHEW", "SWALLOW", "DIGEST", "BELCH", then the StringStatusList is initialized with an array of those strings (in the given order). Multiple change doc types with disjoint status sets may be used simultaneously. When a report representing one change doc is read (and the status attribute is requested), the StringStatusList object is asked for the StringStatus of a particular string as read from the report or supplied at the command line. The StringStatusList object is stored in the change doc's class. This allows me to write expressions like $ss = doc.class.status_of("CHEW") ... doc.status < $ss and get all the docs that have a status of "CUT" and "INSERT". Have I reinvented a wheel that already rolls? -- Jim Crigler #!/home/jcrigler/bin/ruby -w # @(#) stringstatus.rb 1.1 2004/07/06 13:07:47 @(#) class StringStatus < String attr_reader :vec, :val def initialize(val, enumVector) super (enumVector[val]) @val = val @vec = enumVector end def _checkVec(otherStatus) if @vec != otherStatus.vec raise "#{self.class.to_s}: comparing the incomparable" exit(1) end end def <(otherStatus) self._checkVec(otherStatus) @val < otherStatus.val end def ==(otherStatus) self._checkVec(otherStatus) @val == otherStatus.val end def <=(otherStatus) self < otherStatus or self == otherStatus end def >(otherStatus) ! (self <= otherStatus) end def >=(otherStatus) ! (self < otherStatus) end end class StringStatusList def initialize(aVec) @vec = aVec @h = Hash.new (0 ... @vec.length).each do |i| @h[@vec[i]] = StringStatus.new(i, @vec) end end def value(candidate) raise "#{self.class.to_s}: unusable candidate #{candidate}" \ unless @h.has_key? candidate @h[candidate] end end