In order to regularize the process of scanning fixed-size fields in the raw encounter record, we define this base class so all the various encounter fields can use a standardized interface for scanning and flattening field values.
Here is the interface:
# - - - - - c l a s s F i e l d I t e m - - - - -
class FieldItem:
'''Base class for encounter record fields.
Exports:
FieldItem(encounter, value): # Virtual constructor
[ (encounter is the containing BaseEncounter) and
(value is the field value) ->
return a new FieldItem object with those values ]
.encounter: [ as passed to constructor, read-only ]
.value: [ as passed to constructor, read-only ]
FieldItem.scanField(encounter, scan, fieldName): # Static
[ (encounter is a BaseEncounter object) and
(scan is a Scan object) and
(fieldName is an attribute name as a string) ->
if scan starts with a valid field ->
scan := scan advanced past that field
encounter.(fieldName) := an object representing
that field
else ->
scan := scan advanced no further than end of line
Log() +:= error message(s)
raise SyntaxError ]
FieldItem.flatten(value): # Static
[ if value is None ->
return a string of spaces the size of a flattened
field representing this class
if value is a member of this class ->
return value flattened as a string ]
'''
def __init__(self, encounter, value):
'''Default constructor for a FieldItem
'''
self.encounter = encounter
self.value = value
@staticmethod
def scanField(encounter, scan, fieldName):
'''Virtual method.
'''
raise NotImplementedError
The idea here is that derived classes will come up with some
appropriate representation of whatever can occur in the field.
Then the static .scanField() method is used
when we are parsing an encounter line and expect a field of
this type to occur next. The .flatten() method
is used by BaseEncounter.flatten() to assemble
a flat-file record from the constituent fields.
One virtue of this uniform interface is that we can scan a
fixed sequence of fixed-size fields using a table-driven
approach. We can set up a list of tuples ( and work through the list,
calling the className, fieldName).scanField() method for each class
in turn, and storing the resulting object using the given
field name. See Section 7, “scanFieldItems(): Parse a sequence of
FieldItem objects”.