CrLfFileStream as default?

R. A. Harmon harmonra at
Wed Oct 28 15:24:38 UTC 1998

At 05:48 PM 10/25/98 -0600, Dwight Hughes wrote:
>As a quick and modestly sick example of eol formatting there is:

The runs in Text instances breaks also.

>These problems seem to come from code developed on several versions of
>Smalltalk and/or several platforms and cut-and-pasted

I think I am guilty of this, but it is something you ought to be able to do.

>I haven't looked any deeper into the problem than just being aggravated
>by it and whining :-) -- it is easy enough to deal with in other ways.
>Thinking a bit more about it, I think the difficulties in creating a
>one-size-fits-all pathological file filter (which Richard Harmon talks
>about in his messages) makes putting this filtering in as a default a
>bad idea - the assumptions one has to make to filter in any reasonably
>effective way will also turn around and bite you sooner or later.

You very well may be right about the "bite".  I'm not sure it can be done
but it's annoying, and in the USA at least we are guaranteed the right to
life, liberty, and platform independent line termination (PILT).  It's in
the constitution or something.  Seriously, handling line separation is not
"Rocket Science".  I don't think we would ask other users of our software to
deal with this kind of anomaly and programming is difficult enough without
tripping over this.  On the other hand fixing it won't be the cure for
cancer, or end world hunger.

It seems to me that Smalltalk Express handles PILT transparently, but I
wouldn't want to bet my life that it does.  Strings seem to be mostly stored
in StringModel instances as line without line termination.  It has
facilities for coercing a text stream to a desired line end combination, but
normally uses the platform default.

I think with the following proposed set of conventions that PILT could be
effectively achieved and the odd "bite" handled on a case by case basis in
some standard way.

        - Internally all lines end with a carriage return and contain no other
          interline spacing (carriage return, form feed, line feed, and
vertical tab).
        - External text lines end with the platform default unless explicitly
          set to some other line end.
        - External binary lines must deal explicitly with interline spacing
        - External text is the open default.
        - All objects that have lines and internal stuff that depends on them
          (like Text string and runs) must have conversion methods for
          internal to external and back if used made external.
        - You run into something that doesn't follow the convention, send in
a fix
          or at least point it out.

>Since the real problem I see is in filing in such files and getting
>screwy formatting when I browse the code, it might be better to have
>this filter applied by nextChunk during fileIn (it would be nice to base
>this filter on a very general and stupid nextLine method in FileStream -
>just read in anything that is not cr or lf as a line - stop and return
>the line when you see either a cr or lf, if cr or lf is the first char
>seen by nextLine ignore and get next char, etc. -- then put whatever
>end-of-line char you want between lines read).

What I think what might work is the following suggestion in the preview of
the book "The Design Patterns Smalltalk Companion" by Kyle Brown, Sherman
Alpert, and Bobby Woolf"

Missed Opportunities

        For every good opportunity where the Decorator pattern is used,
there seems to be another where it might have been used but wasn't.  The key
to the Decorator pattern is that it is a flexible alternative to
subclassing.  Rather than adding behavior to a class by creating a subclass
of it, we can add the behavior by creating a Decorator for it.  Then that
Decorator can be used to decorate any other class of the same type.  Plus,
Decorators can be nested, so rather than having to choose between a subclass
or its peer, you can decorate with both.
        There are numerous hierarchies that seem like they could benefit
from a more flexible alternative than subclassing.  For example, in the
VisualWorks Stream hierarchy, ExternalReadStream has a subclass called
CodeReaderStream and ExternalWriteStream has a subclass called
CodeWriterStream.  The following diagram shows these classes.  Although
their protocols are counterparts of each other, such reciprocal behavior is
often encapsulated into a single class.  But if there were a single
CodeStream class, how could it be used with both ExternalRead-Streams and
ExternalWriteStreams?  It should be implemented as a Stream Decorator, much
like those in ET++ (DP 183).

It seemed to me when I looked at the Stream hierarchy that it needed an
External layer, and probably needs to be generally refactered also.  That's
why it looked like a lot bigger project than I wanted to tackle right now.

That seems like such a cheesy cop-out as much as I whine about PILT.

Richard A. Harmon          "The only good zombie is a dead zombie"
harmonra at           E. G. McCarthy

More information about the Squeak-dev mailing list