id:sumim:20070614:p1 の続き。
spiral さんに #peek を使ってはどうかというコメントをいただいて、なるほどその手があったか…と気がついたので。
Smalltalk には「位置指定可能ストリーム(a PositionableStream)」というものがあって、順序付きコレクションをこれに変換(ラップ)して使用できます。この位置指定可能ストリームでは、全要素をなめる祭に、通常は終わりがくるまで next というメッセージで要素を取り出すことを繰り返す…というイディオム
| stream | stream := (1 to: 9) readStream. [stream atEnd] whileFalse: [Transcript cr; show: stream next]
を用いるのが常ですが、元の順序付きコレクション同様、do: [:each | ... ] というメッセージ(Ruby の #each にあたる)にも応答できるようになっています。さらに、Squeak Smalltalk では位置指定可能ストリームであれば隣接する要素の“のぞき見(peek)”も可能なので、こんなふうに書くことができるというわけです。
| stream | World findATranscript: nil. Transcript cr. stream := (1 to: 9) readStream. stream do: [:each | Transcript cr; show: {stream peekBack. each. stream peek}].
=> #(nil 1 2) #(1 2 3) #(2 3 4) #(3 4 5) #(4 5 6) #(5 6 7) #(6 7 8) #(7 8 9) #(8 9 nil)
なお、Cincom Smalltlak(VisualWorks)では、PositionableStream が PeekableStream のサブクラスとして定義され、のぞき見可能であることが明示的にされています。