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?