SqueakByExample:10.2
Streams vs. Collections
컬렉션 프로토콜은 컬렉션의 요소에 대한 저장storage, 제거removal 그리고 열거형enumeration등의 작업을 지원하지만, 이러한 연산들을 혼합하는걸 허용하지는 않습니다. 예를 들어, 만약 OrderedCollection 의 구성요소가 do: 메소드를 이용해서 처리하는경우, do: 블록 내부에서 요소의 추가 또는 제거 작업은 불가능합니다. 그리고 컬렉션 프로토콜은, 컬렉션을 선택하며 선택된 컬렉션은 계속 진행하고 선택되지 않은 컬렉션은 진행을 멈추는 작업처럼, 동시에 2 개의 컬렉션을 반복 적용하기 위한 방법들을 제공하지 않습니다. 컬렉션 프로토콜은, 어떤 컬렉션이 계속 앞으로 진행되고 어떤 컬렉션이 그렇지 않은지를 선택함으로써 동시에 2 개의 컬렉션을 반복 적용하기 위한 방법들을 제공하지 않습니다. 이런 작업을 하고싶다면 컬렉션 내부의 index 또는 위치에 대한 참조를 콜렉션의 외부에서 관리할 필요가 있습니다: ReadStream, WriteStream 과 ReadWriteStream 은 정확히 이런경우에 사용할 수 있습니다.
바로 위에서 언급한 3 가지 클래스는 컬렉션을 stream 처리하기위해 만들어졌습니다. 예를들어 아래의 코드는 interval 에 stream 을 만들고 2 개의 요소를 읽어들입니다.
r := ReadStream on: (1 to: 1000).
r next. ⇒ 1
r next. ⇒ 2
r atEnd. ⇒ false
WriteStream 은 컬렉션에 데이터를 쓰기write 할 수 있습니다.
w := WriteStream on: (String new: 5).
w nextPut: $a.
w nextPut: $b.
w contents. ⇒ 'ab'
읽기read 프로토콜과 쓰기write 프로토콜 양쪽을 지원하는 ReadWriteStreams 를 만드는 것도 가능합니다.
WriteStream 와 ReadWriteStream 의 주요 문제는, 스퀵의 경우 array 와 string 을 지원한다는 것입니다. 이 문제는 Nile 이라는 이름의 새로운 라이브러리를 개발함으로서 개선을 진행중입니다만, 현시점에서는 다른 종류의 컬렉션에 stream 처리를 시도한다면, 에러가 납니다:
w := WriteStream on: (OrderedCollection new: 20).
w nextPut: 12. ⇒ raises an error
stream 은 컬렉션 뿐만 아니라 파일 그리고 소켓(network)에도 사용할 수 있습니다. 아래의 예제에서는 test.txt 라 작명된 캐리지 리턴으로 분리된 파일을 만들고 그 파일에 문자열을 작성한 다음 그 파일을 닫고 있습니다.
StandardFileStream
fileNamed: 'test.txt'
do: [:str | str
nextPutAll: '123';
cr;
nextPutAll: 'abcd'].
다음장에서는 이런 프로토콜들을 좀 더 심도있게 알아보겠습니다.