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?
Hi Andrew, My first hunch is that you don't want to change PositionableStream. Because it works on collections and files (because of inheritance). But not on other kind of streams that are not part of the hierarchy, such as sockets. And we are cleaning that part. Instead, some time ago Sven produced a really nice hierarchy of stream decorators. Check the package: Zinc-Character-Encoding-Core There you have ZnBufferedReadStream That implements buffering in an orthogonal way. Maybe it makes more sense to put such method there? Guille On Thu, Nov 2, 2017 at 9:59 AM, Prof. Andrew P. Black <black@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?
-- Guille Polito Research Engineer Centre de Recherche en Informatique, Signal et Automatique de Lille CRIStAL - UMR 9189 French National Center for Scientific Research - *http://www.cnrs.fr <http://www.cnrs.fr>* *Web:* *http://guillep.github.io* <http://guillep.github.io> *Phone: *+33 06 52 70 66 13
On 2 Nov 2017, at 10:10 , Guillermo Polito <guillermopolito@gmail.com> wrote:
My first hunch is that you don't want to change PositionableStream. Because it works on collections and files (because of inheritance). But not on other kind of streams that are not part of the hierarchy, such as sockets. And we are cleaning that part.
Instead, some time ago Sven produced a really nice hierarchy of stream decorators. Check the package:
Zinc-Character-Encoding-Core
There you have
ZnBufferedReadStream
That implements buffering in an orthogonal way. Maybe it makes more sense to put such method there?
I wanted this to be something light-weight. I really donât want to have to wrap my stream in a decorator before peeking ahead. Because Iâm doing this in SmaCC, I implemented #explore: (thatâs the name I chose) in SmaCCLineNumberStream. But I think that the general solution is to put this method in a Trait, so that it can be combined into any stream, whether or not that stream inherits from PositionableStream. There are probably other methods that could go in such a trait too. Actually, the idea of resetting a stream to a prior position is much less general, and easier to implement, then general positionability. Over the weekend I posted an issue that discusses positioning a MultiButeFileStream â thatâs a good example. Here is my implementation â really simple. ``` explore: aBlock "evaluate aBlock with this stream as argument. When done, reset my position to the current position." | savedPosition | savedPosition := self position. [ ^ aBlock value: self ] ensure: [ self position: savedPosition ] ``` Andrew
Yeah, I understand. The thing is that we will remove in the near future MultiByteFileStream. And not all streams have conceptually a position. Today there was a mail from Sven about that. On Mon, Nov 13, 2017 at 2:48 PM, Prof. Andrew P. Black <black@cs.pdx.edu> wrote:
On 2 Nov 2017, at 10:10 , Guillermo Polito <guillermopolito@gmail.com> wrote:
My first hunch is that you don't want to change PositionableStream. Because it works on collections and files (because of inheritance). But not on other kind of streams that are not part of the hierarchy, such as sockets. And we are cleaning that part.
Instead, some time ago Sven produced a really nice hierarchy of stream decorators. Check the package:
Zinc-Character-Encoding-Core
There you have
ZnBufferedReadStream
That implements buffering in an orthogonal way. Maybe it makes more sense to put such method there?
I wanted this to be something light-weight. I really donât want to have to wrap my stream in a decorator before peeking ahead.
Because Iâm doing this in SmaCC, I implemented #explore: (thatâs the name I chose) in SmaCCLineNumberStream. But I think that the general solution is to put this method in a Trait, so that it can be combined into any stream, whether or not that stream inherits from PositionableStream. There are probably other methods that could go in such a trait too.
Actually, the idea of resetting a stream to a prior position is much less general, and easier to implement, then general positionability. Over the weekend I posted an issue that discusses positioning a MultiButeFileStream â thatâs a good example.
Here is my implementation â really simple.
``` explore: aBlock "evaluate aBlock with this stream as argument. When done, reset my position to the current position."
| savedPosition | savedPosition := self position. [ ^ aBlock value: self ] ensure: [ self position: savedPosition ] ```
Andrew
-- Guille Polito Research Engineer Centre de Recherche en Informatique, Signal et Automatique de Lille CRIStAL - UMR 9189 French National Center for Scientific Research - *http://www.cnrs.fr <http://www.cnrs.fr>* *Web:* *http://guillep.github.io* <http://guillep.github.io> *Phone: *+33 06 52 70 66 13
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 <[black@cs.pdx.edu]("mailto:black@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?
Hi. In XStreams this method called #explore: . 2017-11-02 9:59 GMT+01:00 Prof. Andrew P. Black <black@cs.pdx.edu>:
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?
Perhaps #keepStateWhile or something similar might be better than #unchangedDuring ? Sent from Mail for Windows 10 From: Prof. Andrew P. Black Sent: Thursday, November 2, 2017 5:00 AM To: Any question about pharo is welcome Subject: [Pharo-users] Peeking at a stream 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?
On Thu, Nov 2, 2017 at 9:28 PM, Andrew Glynn <aglynn42@gmail.com> wrote:
Perhaps #keepStateWhile or something similar might be better than #unchangedDuring ?
Something like "keepState" was also my first impression, but "During" seems to be the convention for restoring things after a code block completes. Are there methods breaking that convention? cheers -ben *From: *Prof. Andrew P. Black <black@cs.pdx.edu>
*Sent: *Thursday, November 2, 2017 5:00 AM *To: *Any question about pharo is welcome <pharo-users@lists.pharo.org> *Subject: *[Pharo-users] Peeking at a stream
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?
How about #peekAhead? - HH
-------- Original Message -------- Subject: Re: [Pharo-users] Peeking at a stream Local Time: November 2, 2017 9:28 AM UTC Time: November 2, 2017 1:28 PM From: aglynn42@gmail.com To: Any question about pharo is welcome <pharo-users@lists.pharo.org>
Perhaps #keepStateWhile or something similar might be better than #unchangedDuring ?
Sent from [Mail](https://go.microsoft.com/fwlink/?LinkId=550986) for Windows 10
From: [Prof. Andrew P. Black](mailto:black@cs.pdx.edu) Sent: Thursday, November 2, 2017 5:00 AM To: [Any question about pharo is welcome](mailto:pharo-users@lists.pharo.org) Subject: [Pharo-users] Peeking at a stream
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?
participants (6)
-
Andrew Glynn -
Ben Coman -
Denis Kudriashov -
Guillermo Polito -
henry -
Prof. Andrew P. Black