SqueakByExample:3.5
블록 표현식
블록은 프로그램식의 처리를 결정하는 메커니즘을 제공합니다. 블록은 본질적으로 익명 함수입니다. 블록은 value 메시지를 보내 처리합니다. 블록은 확실한 반환문(↑로 입력) 없이 어떠한 값도 반환하지 않으면, 블록 자체 내의 마지막 프로그램식의 값으로 반환됩니다.
[ 1 + 2 ] value ⇒ 3
블록은 매개 변수를 가지며, 각각의 매개 변수는 콜론의 뒤를 따르며 선언됩니다. 수직 바(pipe문자)는 블록의 내용과 매개 변수 선언을 분리합니다. 하나의 매개 변수를 가진 블록을 처리하려면, 하나의 인자를 담은 value: 메시지를 보내야 합니다. 두 개의 매개 변수를 가진 블록은 value:value:를 보내야 하며, 이런 식으로 4개까지 인자를 처리 할 수 있습니다.[1]
[ :x | 1 + x ] value: 2 ⇒ 3
[ :x :y | x + y ] value: 1 value: 2 ⇒ 3
블록에 4개를 넘는 매개 변수가 있다면, 반드시 vaulewithAugument:를 사용해야 하고 배열로 전달해야 합니다. (많은 수의 파라미터를 가진 블록은 종종 설계 문제의 원인이 됩니다)
블록은 메서드의 지역 변수 선언과 같이, 수직 바로 둘러쌓은 지역 변수를 선언하기도 합니다. 지역 변수는 인자 다음에 선언합니다.
[ :x :y | | z | z := x+ y. z ] value: 1 value: 2 ⇒ 3
블록은 실제로 어휘 구분자lexical closure이며, 주변 환경의 변수들을 참조할 수 있습니다. 다음 블록은 그 블록과 가까운 환경의 변수 x를 참조합니다:
| x |
x := 1.
[ :y | x + y ] value: 2 ⇒ 3
블록은 클래스 BlockContext의 인스턴스 입니다. 이것이 의미하는것은, 블록은 오브젝트이므로, 변수에 할당될 수 있고, 모든 다른 오브젝트와 똑같이 인수로서 전달될 수 있다는 것입니다.[2]
충고: 스퀵의 현재 버전 (3.9)은 트루 블록 클로저(true block-closure)를 실제 지원하지 않으며, 그 이유는 블록 인수가 인클로징 메서드의 임시 변수로서 실제적으로 시뮬레이션 되기 때문입니다. 완전한 블록 구분자full block closure를 지원하는 새로운 컴파일러가 있지만, 그 컴파일러는 여전히 작업중이며, 기본적으로 사용되지는 않습니다.
대부분의 애매한 상황에서, 이 문제는 이름 충돌naming conflict을 유발할 수 있습니다. 이 상황은 스퀵이 스몰토크의 이전 구현을 기반으로 하기 때문에 발생합니다. 이런 여러 가지 문제에 직면하혔다면, 메서드 fixTemps의 sender를 보시거나 클로저 컴파일러the closure compiler를 불러오시기 바랍니다.
Notes
- ↑ [:x :y :aa :cc | x + y + ( aa * cc ) ] value: 1 value: 2 value: 3 value:4 대략 이런식으로 4개의 인수를 쓴다는 의미
- ↑ 블록 연산자체도 인수로 전달될 수 있다는 의미입니다. http://workspace.onionmixer.net/mediawiki/index.php?title=Smalltalk_Tips 이 페이지의 "block을 이용한 인자의 처리에 대한 Transcript와 string출력" 부분을 참고해주세요