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?