[ANN] Nile: a trait-based stream library

Damien Cassou damien.cassou at gmail.com
Thu May 3 12:18:19 UTC 2007


> > You would like the framework to let you chain the streams, aren't you?
> > So that you have a stream which interact with another stream.
>
> Yes, pipes of streams.

I've just created a decoder in a trait and it is highly pluggable :-)
Let's see an example:

testCombineWithNumberReader
  | stream |
  stream := NSSelectStream
                        selectBlock: [:each | each even]
                        inputStream: (NSNumberReader
                                                    inputStream:
(NSReadableCollectionStream on: '1420 245 211 12')).
  self deny: stream atEnd.
  self assert: stream peek = 1420.
  self assert: stream next = 1420.
  self deny: stream atEnd.
  self assert: stream peek = 12.
  self assert: stream next = 12.
  self assert: stream atEnd


This code uses three stream:
- NSSelectStream reads its input and only returns elements matching
the selectBlock (http://wiki.cs.uiuc.edu/PatternStories/SelectStream)
- NSNumberReader is waiting for characters on its input and converts
them to numbers. Spaces separate numbers.
- NSReadableCollectionStream is equivalent to ReadStream.

The implementation part is really cool. NSNumberReader is made of:

- a constructor
- 3 getters and 3 setters
- a #realNext method:
NSNumberReader>>realNext
  |number|
  [self inputStream peekFor: Character space] whileTrue.
  self inputStream atEnd ifTrue: [NSStreamAtEndError signal].
  number := (self inputStream upTo: Character space) asNumber.
  ^ number

That's all. Nothing more is needed to create NSNumberReader. The other
methods come from a trait.

NSSelectBlock is implemented in exactly the same way. It's #realNext is:

NSSelectBlock>>realNext
  self inputStream do: [:each | (selectBlock value: each) ifTrue: [^ each]].
  NSStreamAtEndError signal.

What do you think?

-- 
Damien Cassou



More information about the Squeak-dev mailing list