GnuSmalltalkUsersGuide:BaseChapter 082

From 흡혈양파의 번역工房
Jump to: navigation, search
Generator

Generator

네임스페이스 Smalltalk에 정의됨

슈퍼클래스: Stream

범주: 스트림-생성기


Generator 객체는 블록을 이용해 많은 리턴 값의 Stream을 정의하는 방법을 제공한다. 리턴 값은 필요 시 한 번에 하나씩 계산되므로 유한일 필요가 없다.
생성기 블록은 "Generator on:[...]"을 이용해 Generator로 변환된다. Generator 자체는 블록으로 전달되며, #next, #peek, #atEnd or #peekFor: 와 같은 메시지가 생성기로 전송되는 즉시 블록의 실행이 시작/재개되어 생성기의 #yield: 메서드가 호출될 때까지 지속된다: 이후 #yield: 의 인자는 Generator의 다음 요소가 될 것이다. #yield: 를 호출하지 않고 블록이 끝까지 지속될 경우 Generator는 더 이상 요소를 생성하지 않고 #atEnd는 true를 리턴할 것이다.
자신만의 클래스를 작성하고 모든 생성기의 로컬 변수를 인스턴스 변수로서 보관함으로써 수동적으로 생성기의 효과를 누릴 수도 있다. 예를 들어, 변수를 0으로 설정하여 #next 메서드가 그것을 증가시킨 후 리턴하도록 만들면 정수 리스트를 리턴할 수 있다. 하지만 다소 복잡한 생성기의 경우, 그에 해당하는 클래스를 작성하기가 훨씬 복잡해질 수 있다 (그리고 #peek, #peekFor: , #atEnd 라도 지원하길 원한다치면 비효율성이나 코드 중복을 야기할지도 모른다): 일반적으로 #do: 와 같은 인터페이스를 제공하기란 쉽지만 Stream과 같은 인터페이스의 제공은 그렇지 않다 (바이너리 트리를 생각해보라).
생성기라는 개념은 다른 프로그래밍 언어에서 비롯되었는데, 특히 이 인터페이스는 Scheme 스트림과 Python 생성기와 많이 닮았다. 하지만 Python은 이후 Icon의 개념을 변경시켜 생성기를 중심으로 한다. Icon에서는 모든 표현식과 함수 호출이 생성기처럼 행동하며, 문(statement)이 스칼라를 관리할 경우 해당 생성기가 제공하는 모든 결과를 자동으로 사용한다; 반면 Icon은 Python이나 Smalltalk와 달리 생성기를 일급 객체로 표현하지 않는다.


Generator 클래스: 인스턴스 생성

inject: aValue into: aBlock

무한 생성기를 리턴하라; 첫 번째 항목은 aValue이고, 그에 따라오는 항목들은 이전 값을 aBlock으로 전달함으로써 얻는다.

on: aBlock

생성기를 리턴하고 aBlock으로 전달하라. #next를 생성기로 전달하면 블록의 실행이 시작되고, #yield:가 블록으로부터 생성기로 전송되는 즉시 블록의 실행은 중지될 것이다.

on: aCollection do: aBlock

생성기를 리턴하라; aCollection의 각 항목마다 aBlock을 평가하여 생성기와 항목을 전달하라.


Generator: 스트림 프로토콜

atEnd

더 많은 데이터를 생성 가능한지 응답하라.

next

다음 값을 생성할 때까지 또는 더 이상 어떤 것도 생성할 수 없다고 결정할 때까지 생성기를 평가하라.

peek

생성기가 다음 값을 생성하거나 더 이상 어떤 것도 생성할 수 없다고 결정할 때까지 생성기를 평가하고 값을 저장하여 #peek 또는 #next가 다시 그 값을 리턴하도록 한다.

peekFor: anObject

생성기가 다음 값을 생성하거나 더 이상 어떤 것도 생성할 수 없다고 결정할 때까지 생성기를 평가하고, anObject와 같지 않을 경우 값을 저장하여 #peek 또는 #next가 다시 그 값을 리턴하도록 한다.

yield: anObject

생성기로부터 입력이 시작되면 블록 내 코드가 실행되고 제어흐름은 소비자에게 돌아간다. 소비자로부터 입력이 시작되면 연속(continuation) 이후의 코드가 실행되어 생성기 블록의 실행이 재개된다.


Notes