J
James B Crigler
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] = 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
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] = 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