Normally, the .__iter__ method of a class is
supposed to return an object that has a .next()
method that can be called to return each generated value.
However, the .__iter__() method itself can be a
generator, and that is the approach we take.
Basically, this method is the main loop that reads through the lines of the input file.
# - - - B a s e C o m p i l e r . _ _ i t e r _ _ - - -
def __iter__(self):
'''Iterator for BaseCompiler: generate all BaseEncounter records
'''
Lines are classified as one of four types; see the specification.
Empty lines, or lines containing only whitespace, are ignored.
Lines starting with “@” (PAGE_SYMBOL) are page header lines. Assuming the line has a valid
format, it is converted into a PageHeader object
and stored in self.pageHeader.
Lines starting with “#” (PREFIX_SYMBOL) are new band prefix lines. If it is
valid, it is stored in self.prefix as a Prefix object.
All other lines are assumed to be encounter lines. Each line
that is valid causes the generation of one BaseEncounter object using the Python yield statement.
So that this method can generate values, we must call the
self.classify() function in a for loop, and yield any values it generates.
See Section 19.10, “BaseCompiler.classify(): Which kind of line is
it?”.
#-- 1 --
while not self.scan.atEndFile:
#-- 1 body --
# [ if the line in self.scan is empty or contains only
# whitespace ->
# I
# else if the line in self.scan is a valid new page
# header ->
# self.pageHeader := a PageHeader object representing
# that line
# else if the line in self.scan is a valid band prefix line
# in the context of self ->
# self.prefix := a Prefix object representing that line
# else if the line in self.scan is a valid encounter line
# in the context of self ->
# yield a BaseEncounter object representing that line
# else ->
# Log() +:= error message(s)
# In any case ->
# self.scan := self.scan advanced to the start of the
# next line ]
for x in self.classify():
yield x
self.scan.nextLine()
When the file is exhausted, we close self.scan
object and raise StopIteration to signal the end of
the iterator.
#-- 2 --
self.scan.close()
raise StopIteration