Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!godot.cc.duq.edu!newsgate.duke.edu!news.mathworks.com!newsfeed.internetmci.com!howland.reston.ans.net!blackbush.xlink.net!ins.net!heeg.de!gustav!hmm
From: hmm@gustav (Hans-Martin Mosner)
Subject: Re: Raising End of Stream Signals in VW2.5
Message-ID: <DuxpzD.5tH@heeg.de>
Sender: uucp@heeg.de
Organization: Georg Heeg Objektorientierte Systeme, Dortmund, FRG
X-Newsreader: TIN [version 1.2 PL2]
References: <4sofqp$6vb@bcarh8ab.bnr.ca>
Date: Mon, 22 Jul 1996 07:54:49 GMT
Lines: 59

Mike Smith P125 (mismith@bnr.ca) wrote:
: When an attempt is made to read past the end of an InternalStream in VW,
: the following method #pastEnd is called:

: 	^Signal noHandlerSignal
: 		handle: [:ex | ex parameter proceedWith: nil]
: 		do: [self class endOfStreamSignal raiseRequestFrom: self].

: Note that the receiver of the handle:do: does not subsume the EOS raised
: in the do: clause. In order for the handle: clause to be invoked, the
: signal must pass all the way up the stack, find no EOS handlers, raise
: the no handler exception, and then be caught here.

: This causes a problem with the new print policies. Their #nextTokenOn:
: methods all call next without checking for EOS, expecting #pastEnd to
: return nil in that case. This leads to unexpected results if you have
: and EOS catcher anywhere else on the stack while printing. 

: #pastEnd has been around since VW1.0 at least, so there must be a reason
: for this that eludes me. Is the moral that applications should never
: try to catch EOS signals (any more than say, generic ones)?

print policies have not been around that long, and I assume that ParcPlace
simply did not cross-check the EOS mechanism with print policies after
they were introduced. Otherwise they should have equipped them with their
own EOS handling

In cases such as this, your EOS handler should check that EOS happened
on the right stream, and reject the signal if it didn't. Then the
noHandlerSignal handler in #pastEnd will do its thing.
The #pastEnd method sets the originator to be the stream
on which EOS happened. Do a 'print it' on the following code, and see
what happens of you remove the line rejecting the signal.

	Hans-Martin

| in out |
in := 'test' readStream.
out := (String new: 10) writeStream.
Stream endOfStreamSignal handle: [:ex |
	ex originator == in ifFalse: [ex reject].
	out nextPutAll: '<EOS>'; cr.
	ex proceed]
do: [| c word c2 |
	[c := in next.
	c == nil] whileFalse: [
		word := (String new: 3 withAll: c) readStream.
		[c2 := word next.
		c2 == nil]
			whileFalse: [out nextPut: c].
		out cr]].
out contents


--
+--- Hans-Martin Mosner -------- Senior Smalltalk Guru ---+
| These opinions are entirely ficticious.  Any similarity |
| to real opinions is purely coincidental and unintended. |
+--- <hmm@heeg.de> ------ URL:http://www.heeg.de/~hmm/ ---+
