Hi Sven,
On Wed, Apr 04, 2018 at 11:32:02AM +0200, Sven Van Caekenberghe wrote:
> Somehow, somewhere there was a change to the implementation of the
> primitive called by some streams' #atEnd.
That's a proposed change by me, but it hasn't been integrated yet. So
the discussion below should apply to the current stable vm (from August
last year).
> IIRC, someone said it is implemented as 'remaining size being zero'
> and some virtual unix files like /dev/random are zero sized.
Currently, for files other than sdio (stdout, stderr, stdin) it is
effectively defined as:
atEnd := stream position >= stream size
And, as you say, plenty of virtual unix files report size 0.
> Now, all kinds of changes are being done image size to work around this.
I would phrase this slightly differently :-)
Some code does the right thing, while other code doesn't. E.g.:
MultiByteFileStream>>upToEnd is good, while
FileStream>>contents is incorrect
> I am a strong believer in simple, real (i.e. infinite) streams, but I
> am not sure we are doing the right thing here.
>
> Point is, I am not sure #next returning nil is official and universal.
>
> Consider the comments:
>
> Stream>>#next
> "Answer the next object accessible by the receiver."
>
> ReadStream>>#next
> "Primitive. Answer the next object in the Stream represented by the
> receiver. Fail if the collection of this stream is not an Array or a String.
> Fail if the stream is positioned at its end, or if the position is out of
> bounds in the collection. Optional. See Object documentation
> whatIsAPrimitive."
>
> Note how there is no talk about returning nil !
>
> I think we should discuss about this first.
>
> Was the low level change really correct and the right thing to do ?
The primitive change proposed doesn't affect this discussion. It will
mean that #atEnd returns false (correctly) sometimes, while currently it
returns true (incorrectly). The end result is still incorrect, e.g.
#contents returns an empty string for /proc/cpuinfo.
You're correct about no mention of nil, but we have:
FileStream>>next
(position >= readLimit and: [self atEnd])
ifTrue: [^nil]
ifFalse: [^collection at: (position := position + 1)]
which has been around for a long time (I suspect, before Pharo existed).
Having said that, I think that raising an exception is a better
solution, but it is a much, much bigger change than the one I proposed
in https://github.com/pharo-project/pharo/pull/1180.
Cheers,
Alistair
> Note also that a Guille introduced something new, #closed which is related to
> the difference between having no more elements (maybe right now, like an open
> network stream) and never ever being able to produce more data.
>
> Sven
>
>
>