I use the approach you mention, restoring stream position, in my ParrotTalk 
code, both in Pharo and in Java. I am not peeking more than one character but I 
had to implement peek in Java and your code example is how I did this code.

- HH

On Thu, Nov 2, 2017 at 04:59, Prof. Andrew P. Black 
<[bl...@cs.pdx.edu]("mailto:bl...@cs.pdx.edu";)> wrote:

> I sometimes find, when working with a stream, that I need to "peek ahead" a 
> few items, without disturbing the state of the stream. The message stream 
> peek gives me the next item, but doesn’t generalize to multiple items,   So I 
> end up writing code like this:
>
>     findSomething
> | savedPosition result |
> savedPosition := stream position.
> stream position: start.
> "code involving various manipulations of stream, including stream next"
> result := stream position + 1.
> stream position: savedPosition.
> ^ result
>
> This code involves at least two temps, is not very easy to read, and risks 
> not resetting the stream properly if I do a return.
>
> It seems to me that a better solution would be what Kent Beck calls an 
> "execute around" method:
>
>     findSomething
> ^ stream unchangedDuring: [ :s |
> "code involving various manipulations of stream, including stream next"stream 
> position + 1 ]
>
> I’m not sure that I like the name #unchangedDuring:; perhaps you can think of 
> a better one?
>
> The  implementation of this would be
>
> PositionableStream >> #unchangedDuring: aBlock
> "execute aBlock with self as argument. Ensure that when this method returns,
> I still have my current state."
>
> | savedPosition |savedPosition := self position.
> ^ [ aBlock value: self ] ensure: [ self position: savedPosition ]
>
> or perhaps
>
> PositionableStream >> #unchangedDuring: aBlock
> "execute aBlock with self as argument. Ensure that when this method returns,
> I still have my current state."
> ^ [ aBlock value: self copy ]
>
> which might be better in the case that the stream is a file stream and aBlock 
> causes the buffer to be refreshed from the disk.
>
> - Do other Smalltalks have a method like this?
> - Does it already exist in Pharo, somewhere that I’ve failed to look?
> - Would it be a worthwhile addition to Pharo?
> - What would be a good name?

Reply via email to