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