At 05:48 PM 10/25/98 -0600, Dwight Hughes wrote:
As a quick and modestly sick example of eol formatting there is:
[snip]
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.
[snip]
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 characters. - 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).
[snip]
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@webname.com E. G. McCarthy
squeak-dev@lists.squeakfoundation.org