이 글은 Canol Gokel님이 만든 Computer Programming using GNU Smalltalk를 읽고 정리한 것이다.
aBlock whileTrue: anotherBlock
메세지 whileTrue:
는 Boolean
객체에 보내는 것이 아니라 블록 객체에 보낸다.
메세지를 받으면 리시버 블록 객체가 평가되고 결과가 true
객체이면 인자로 넘긴 블록 객체가 실행된다.
이때 리시버 블록이 다시 한 번 평가되고 여전히 결과가 true
이면 인자로 넘긴 블록 객체가 다시 실행된다.
리시버 블록의 평가 결과가 false
가 될 때까지 이 과정을 반복한다.
"average.st"
"A program which evaluates the sum of the numbers entered to demonstrate the whileTrue: message."
| sum enteredIntegers lastEnteredInteger |
sum := 0.
enteredIntegers := 0.
[ lastEnteredInteger ~= -1 ] whileTrue: [
Transcript cr; show: 'Please enter a number. To exit the program enter -1: '.
lastEnteredInteger := stdin nextLine asInteger.
sum := sum + lastEnteredInteger.
enteredIntegers := enteredIntegers + 1.
Transcript show: 'The average of the numbers entered so far is: ', (sum / enteredIntegers) printString; cr.
]
~=
는 두 객체가 서로 같지 않은지 확인하는 연산자이다.
aNumber to: anotherNumber do: aBlock
숫자 aNumber
에서 시작해서 anotherNumber
가 될 때까지 aBlock
객체를 실행한다.
루프를 한 번 돌 때마다 숫자를 1씩 증가시킨다.
블록 인자를 이용하면 현재 루프를 돌고 있는 숫자도 참조할 수 있다.
whileTrue:
는 루프를 몇 번 돌지 특정할 수 없어서 indefinite loop라고 부르지만 to:do:
는 반복의 횟수를 특정할 수 있어서 definite loop라고 부른다.
"5_lines.st"
"A program which prints 5 lines to demonstrate the usage of to:do: message."
1 to: 5 do: [:x |
Transcript show: 'This is the ', x printString, '. line.'; cr.
]
블록 인자를 적지 않으면 에러가 난다.
반복 인덱스를 1씩 증가하는 것이 아니라 원하는만큼 조정하고 싶을 때는 to:by:do:
를 사용한다.
aNumber to: anotherNumber by: step do: aBlock
"tobydo.st"
"A program to demonstrate the usage of to:by:do: message."
1 to: 10 by: 2 do: [:x |
Transcript show: 'This is the ', x printString, '. line.'; cr.
]
반복 인덱스는 반대 방향으로 할 수도 있다.
"tobydo_backwards.st"
"A program to demonstrate the backward capability of to:by:do: message."
5 to 1: by: -1 do: [:x |
Transcript show: 'Oh my god! I''m counting backwards! This is the ', x printString, '. line!'; cr.
]