[M3devel] Subclassing Wr.T

hendrik at topoi.pooq.com hendrik at topoi.pooq.com
Tue Nov 10 19:32:54 CET 2009


Am I missing something obvious, or am I going about this in completely 
the wrong way.

I wanted to make a writer that would admit the usual procedures for 
writing to an output stream (such as PutChar and PutText and PutString 
and so forth, and also a few for keeping track of indentation, such as

  indent(Wr.T) for increasing the current indentation one level
  outdent(Wr.T) for decreasing the current indentation one level
  newline(Wr.T) for emitting a newline and enough spaces to accomplish 
                the current indentation.

The obvious technique is to subclass Wr.T, making, say, WrI.T, which has 
an extra field, depth, to keep track of the current indentation level.  
Then I have all the Wr procedures available, and, in fact, can use any 
other procedures in the system that write to a Wr.T (although any 
newlines they emit won't be indented).

But this won't work, because objects like Stdio.stdout are also made by 
subclassing Wr.T, and I can't subclass in both directions.  What I could 
do is take all the subclasses of Wr.T that provide different kinds 
of writing and subclass each of them, but that would yield many 
different WrI.T classes with no unifying Wr.I class above them; of 
course, a unifying WrI.T class would end up requiring multiple 
inheritance.

Now the usual way to avoid multiple inheritance is to delegate.  I 
have WrI.T contain a reference to another instance of Wr.T (which I 
will call subwriter).  I let WrI.T inherit from Wr.I so that calls to 
the the Wr procedures will work, but I reimplement the primitives seek, 
putString, length, flush, and close to just call the subwriter's 
versions of these methods.  These primitives are, acter all, what the 
procedures in Wr use to do their writing.  Infortunately, I can't 
actually do this delegation, because those primitives access the fields 
buff, st, lo, hi, cur, which will now be the right fields of the wrong 
object.

Am I stuck here?  Or is there some completely different way of looking 
at the problem?  Or is there already a writer somewhere that already 
takes care of all this which I could use or learn from?

Of course there are half a dozen ways around this that involve bypassing 
the tools the Modula 3 library provided altogether, and definint WrI.T 
with no family relationship to any of the existing IO classes (with the 
resulting lack of interoperability).  But I'd prefer to work with the 
language instaed of against it.

-- hendrik




More information about the M3devel mailing list