<br><br><div class="gmail_quote">On Fri, Nov 27, 2009 at 4:40 PM, Igor Stasenko <span dir="ltr"><<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
2009/11/28 Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>>:<br>
<div class="im">> 2009/11/27 Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>>:<br>
>> An approach I like is to add an endOfStreamValue inst var to Stream and<br>
>> answer its value when at end. This way nil does not have to be the<br>
>> endOfStreamValue, for example -1 might be much more convenient for a binary<br>
>> stream, and streams can answer nil without confusing their clients. atEnd<br>
>> can be implemented as<br>
>> atEnd<br>
>> ^self peek = self endOfStreamValue<br>
>> You can arrange to make streams raise an end-of-stream exception instead of<br>
>> the endOfStreamValue by using some convention on the contents of<br>
>> endOfStreamValue, such as if it is == to the stream itself (although I note<br>
>> that in the Teleplace image the exception EndOfStrean is defined bit not<br>
>> used).<br>
>><br>
>> Of course, stream primitives get in the way of adding inst vars to stream<br>
>> classes ;)<br>
>> IMO this is a much more useful scheme than making nil the only endOfStream<br>
>> value.<br>
>><br>
><br>
> Last time I proposed to have an inst var endOfStreamAction was here<br>
> <a href="http://lists.gforge.inria.fr/pipermail/pharo-project/2009-June/009536.html" target="_blank">http://lists.gforge.inria.fr/pipermail/pharo-project/2009-June/009536.html</a><br>
> .<br>
> Abusing nil value -> nil, I could even let this inst var<br>
> un-initialized and be backward compatible<br>
> (initializing with a ValueHolder on nil would do as well)<br>
><br>
<br>
</div>Nicolas, have you considered introducing methods which allow<br>
graciously handle the end-of-stream while reading?<br>
Something like:<br>
<br>
nextIfAtEnd: aBlock<br>
and<br>
next: number ifAtEnd: aBlock<br>
<br>
<br>
then caller may choose to either write:<br>
<br>
char := stream nextIfAtEnd: [nil]<br>
<br>
or handle end of stream differently, like leaving the loop:<br>
<br>
char := stream nextIfAtEnd: [^ results]<br>
<br>
the benefit of such approach that code which reads the stream , don't<br>
needs to additionally<br>
test stream state (atEnd) in iteration between #next sends neither<br>
requires some unique value (like nil) returned by #next<br>
when reaching end of stream.<br></blockquote><div><br></div><div>IMO the block creation is too expensive for streams. The defaultHandler approach for and EndOfStream exception is also too expensive. The endOfStreamValue inst var is a nice trade-off between flexibility, efficiency and simplicity. You can always write</div>
<div> [(value := stream next) ~~ stream endOfStreamValue] whileTrue:</div><div> [...do stuff...</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
> Nicolas<br>
<div><div></div><div class="h5">><br>
<br>
<br>
--<br>
Best regards,<br>
Igor Stasenko AKA sig.<br>
<br>
</div></div></blockquote></div><br>