SqueakByExample:4.3: Difference between revisions
Onionmixer (talk | contribs) (번역수정) |
Onionmixer (talk | contribs) (번역수정) |
||
Line 3: | Line 3: | ||
3종류의 메시지는, 명쾌한 방식으로 메시지가 작성될 수 있도록 해주는 각각 다른 우선순위를 가지고 있습니다. | 3종류의 메시지는, 명쾌한 방식으로 메시지가 작성될 수 있도록 해주는 각각 다른 우선순위를 가지고 있습니다. | ||
# 단항 메시지는 항상 먼저 | # 단항 메시지는 항상 먼저 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 보내집니다. | ||
# 괄호 안에 있는 메시지는 어떤 종류의 메시지 보다 먼저 보내집니다. | # 괄호 안에 있는 메시지는 어떤 종류의 메시지 보다 먼저 보내집니다. | ||
# 동일한 종류의 메시지는 왼쪽에서부터 오른쪽으로 계산됩니다. | # 동일한 종류의 메시지는 왼쪽에서부터 오른쪽으로 계산됩니다. | ||
이 규칙들은 매우 자연스러운 읽기 순서로 이어집니다. 지금, 만약 여러분이, 여러분이 원하는 순서대로 메시지가 | 이 규칙들은 매우 자연스러운 읽기 순서로 이어집니다. 지금, 만약 여러분이, 여러분이 원하는 순서대로 메시지가 전달되기를 원한다면, 그림 4.3에서 볼수있듯이 원하는만큼 괄호들을 추가로 사용하면 됩니다. 이 그림에서, 메시지 yellow는 단항 메시지이며, 메시지 color:는 키워드 메시지이므로, 우선순위에 의해 메시지 전송식 Color yellow 가 먼저 전달됩니다. 괄호에 있는 메시지 전송식이 전달되지만, 굳이 Color yellow 주위에(필요없는) 괄호를 넣은 것은 단지 그것이 먼저 전달될 것이라는 것을 추가로 강조한 것입니다. 나머지 부분은 이런점들을 보여준 것입니다. | ||
[[image:uKeyUn.png|none|800px|thumb|그림 4.3: | [[image:uKeyUn.png|none|800px|thumb|그림 4.3: Color yellow 가 전달되어야 하기때문에 단항메시지(yellow)가 먼저 전송됩니다. 이 단항 메세지는 aPen color:의 메세지로 전달될 color 오브젝트를 반환합니다.]] | ||
===단항 > 바이너리 > 키워드=== | ===단항 > 바이너리 > 키워드=== | ||
단항 | 단항 메시지가 처음으로 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 전달됩니다. 또한 다른 종류의 메시지보다 단항 메시지가 더 높은 우선권을 가지게 됩니다. | ||
<center>{{HighlightDoubleBox| | <center>{{HighlightDoubleBox| | ||
Rule One.단항 메시지는 처음으로 | Rule One.단항 메시지는 처음으로 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 전달됩니다.<br> | ||
Unary > Binary > Keyword | Unary > Binary > Keyword | ||
}}</center> | }}</center> | ||
아래의 예제에서 볼 수 있듯이, 스몰토크의 문법 규칙은 일반적으로 메시지 전달을 자연스럽게 읽을 수 있도록 합니다: | |||
{| style="border: 1px solid black;" | {| style="border: 1px solid black;" | ||
Line 34: | Line 34: | ||
안타깝게도, 규칙들은 산술적 | 안타깝게도, 규칙들은 산술적 메시지를 전달 하기에는 너무 단순하므로, 바이너리 연산자들에 대한 우선순위를 원할 때마다 괄호를 넣는것이 좋습니다. | ||
{| style="border: 1px solid black;" | {| style="border: 1px solid black;" | ||
Line 54: | Line 53: | ||
여기서 | 여기서 Boolean클래스의 메소드가 추상적인건지 궁금하기는 합니다.<ref name="주석4-1">사실, 비슷한 수준이지만 더 간단한 표현을 쓸 수 있습니다: Boolean methodDict select: #isAbstract thenCollect: #selector</ref>. 우리는 인수 클래스의 메서드 사전 키들을 위해, 몇 가지 인수 클래스인 aClass를 요청하였으며, 추상적인 클래스의 메서드들을 선택하였습니다. 그 다음, 우리는 실체적인 값 Boolean에 인수 aClass를(augument aClass)를 묶었습니다. 우리는 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 이항 메시지 >> 보내는 용도로만 쓰일 괄호가 필요합니다. 결과는 우리에게 어떤 메서드들이, True 또는 False로 나타나는 Boolean의 실체적 서브클래스들로, 실행되어야만 할 것인지를 보여줍니다. | ||
우리는 인수 클래스의 메서드 사전 키들을 위해, 몇 가지 인수 클래스인 aClass를 요청하였으며, 추상적인 클래스의 메서드들을 선택하였습니다. 그 다음, 우리는 실체적인 값 Boolean에 인수 aClass를(augument aClass)를 묶었습니다. 우리는 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 이항 메시지 >> 보내는 용도로만 쓰일 괄호가 필요합니다. 결과는 우리에게 어떤 메서드들이, True 또는 False로 나타나는 Boolean의 실체적 서브클래스들로, 실행되어야만 할 것인지를 보여줍니다. | |||
'''Exmaple.''' 메시지 '''aPen color: Color yellow''' 에서, 클래스 Color와 aPen에 발송된 키워드 메시지 Color:에는 오직 하나의 단항 메시지가 존재합니다. 첫 번째로 단항 메시지가 발송되므로, 메시지 발송 '''Color yellow'''가 발송됩니다. (1) 이것은 예 4.1에 보이는 것처럼 메시지 '''aPen color: aColor''' (2)의 인수로서 패스되는 color 오브젝트입니다. 그림 4.3은 어떻게 메시지가 발송되는지 그림으로 보여줍니다. | '''Exmaple.''' 메시지 '''aPen color: Color yellow''' 에서, 클래스 Color와 aPen에 발송된 키워드 메시지 Color:에는 오직 하나의 단항 메시지가 존재합니다. 첫 번째로 단항 메시지가 발송되므로, 메시지 발송 '''Color yellow'''가 발송됩니다. (1) 이것은 예 4.1에 보이는 것처럼 메시지 '''aPen color: aColor''' (2)의 인수로서 패스되는 color 오브젝트입니다. 그림 4.3은 어떻게 메시지가 발송되는지 그림으로 보여줍니다. |
Revision as of 13:49, 3 March 2013
메시지 구성하기
3종류의 메시지는, 명쾌한 방식으로 메시지가 작성될 수 있도록 해주는 각각 다른 우선순위를 가지고 있습니다.
- 단항 메시지는 항상 먼저 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 보내집니다.
- 괄호 안에 있는 메시지는 어떤 종류의 메시지 보다 먼저 보내집니다.
- 동일한 종류의 메시지는 왼쪽에서부터 오른쪽으로 계산됩니다.
이 규칙들은 매우 자연스러운 읽기 순서로 이어집니다. 지금, 만약 여러분이, 여러분이 원하는 순서대로 메시지가 전달되기를 원한다면, 그림 4.3에서 볼수있듯이 원하는만큼 괄호들을 추가로 사용하면 됩니다. 이 그림에서, 메시지 yellow는 단항 메시지이며, 메시지 color:는 키워드 메시지이므로, 우선순위에 의해 메시지 전송식 Color yellow 가 먼저 전달됩니다. 괄호에 있는 메시지 전송식이 전달되지만, 굳이 Color yellow 주위에(필요없는) 괄호를 넣은 것은 단지 그것이 먼저 전달될 것이라는 것을 추가로 강조한 것입니다. 나머지 부분은 이런점들을 보여준 것입니다.
단항 > 바이너리 > 키워드
단항 메시지가 처음으로 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 전달됩니다. 또한 다른 종류의 메시지보다 단항 메시지가 더 높은 우선권을 가지게 됩니다.
Rule One.단항 메시지는 처음으로 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 전달됩니다.
Unary > Binary > Keyword
아래의 예제에서 볼 수 있듯이, 스몰토크의 문법 규칙은 일반적으로 메시지 전달을 자연스럽게 읽을 수 있도록 합니다:
1000 factorial / 999 factorial | ⇒ 1000 |
2 raisedTo: 1 + 3 factorial | ⇒ 128 |
안타깝게도, 규칙들은 산술적 메시지를 전달 하기에는 너무 단순하므로, 바이너리 연산자들에 대한 우선순위를 원할 때마다 괄호를 넣는것이 좋습니다.
1+2*3 | ⇒ 9 |
1 + (2 * 3) | ⇒ 7 |
약간 더 복잡한 (!) 다음 예는 심지어 복잡한 스몰토크 표현식도 자연스럽게 읽힐 수 있다는 것을 훌륭하게 보여줍니다:
[:aClass | aClass methodDict keys select: [:aMethod | (aClass>>aMethod) isAbstract ]]
value: Boolean ⇒ an IdentitySet(#or: #| #and: #& #ifTrue: #ifTrue:ifFalse: #ifFalse: #not #ifFalse:ifTrue:)
여기서 Boolean클래스의 메소드가 추상적인건지 궁금하기는 합니다.[1]. 우리는 인수 클래스의 메서드 사전 키들을 위해, 몇 가지 인수 클래스인 aClass를 요청하였으며, 추상적인 클래스의 메서드들을 선택하였습니다. 그 다음, 우리는 실체적인 값 Boolean에 인수 aClass를(augument aClass)를 묶었습니다. 우리는 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 이항 메시지 >> 보내는 용도로만 쓰일 괄호가 필요합니다. 결과는 우리에게 어떤 메서드들이, True 또는 False로 나타나는 Boolean의 실체적 서브클래스들로, 실행되어야만 할 것인지를 보여줍니다.
Exmaple. 메시지 aPen color: Color yellow 에서, 클래스 Color와 aPen에 발송된 키워드 메시지 Color:에는 오직 하나의 단항 메시지가 존재합니다. 첫 번째로 단항 메시지가 발송되므로, 메시지 발송 Color yellow가 발송됩니다. (1) 이것은 예 4.1에 보이는 것처럼 메시지 aPen color: aColor (2)의 인수로서 패스되는 color 오브젝트입니다. 그림 4.3은 어떻게 메시지가 발송되는지 그림으로 보여줍니다.
예 4.1: aPen color: Color yellow의 처리 분석하기 | |||
aPen color | : Color yellow | ||
(1) | Color yellow | "단항 메시지가 먼저 발송되고" | |
⇒ aColor | |||
(2) | aPen color | : aColor | "그 다음 키워드 메시지가 발송됩니다" |
Example. 메시지 aPen go:100 + 20에서, 바이너리 메시지 +20과 키워드 메시지 go:가 있습니다. 바이너리 메시지는 키워드 메시지 전에 발송되므로, 100+20이 먼저 발송됩니다. (1): 메시지 +20은 오브젝트 100에 발송되며, 숫자 120을 리턴합니다. 그 다음, 메시지 aPen go: 120은 인수로서, 120과 함께 발송됩니다 (2). 예 4.2는 메시지가 어떻게 실행되는지를 보여줍니다.
예 4.2: aPen go: 100 + 20 분해하기 | |||
aPen go | : 100 + 20 | ||
(1) | 100 + 20 | "이항 메시지가 먼저 발송되고" | |
⇒ 120 | |||
(2) | aPen go | : 120 | "그 다음 키워드 메시지가 전송됩니다" |
그림 4.4: 이항 메시지가 키워드 메시지 이전에 발송 되었습니다. | 그림 4.5: Pen new go: 100 + 20 분해 |
Example. 연습으로서, 우리는 여러분이 한 개의 단항 메시지와 한 개의 키워드 메시지 그리고 한 개의 이항 메시지(그림 4.5를 보십시오)로 구성되어 있는 Pen new go:100+20의 계산을 분해합니다.
괄호 우선
Rule Two. 괄호로 묶인 메시지는 다른 메시지 보다 먼저 발송됩니다.
(메시지)> 단항 메시지>이항 메시지>키워드 메시지
1.5 tan rounded asString = (((1.5 tan) rounded) asString) ⇒ true "parentheses not needed here"
3 + 4 factorial ⇒ 27 "(not 5040)"
(3 + 4) factorial ⇒ 5040
여기서 우리는 실행하기 전 lowMajorScaleOn:을 강제로 보내기 전에 괄호가 필요합니다.
(FMSound lowMajorScaleOn: FMSound clarinet) play
"(1) send the message clarinet to the FMSound class to create a clarinet sound.
(2) send this sound to FMSound as argument to the lowMajorScaleOn: keyword
message.
(3) play the resulting sound."
Exmaple. 메시지 (65@325 extent: 134 @ 100) center는 상단 왼쪽 꼭지점이 (65,325)이며 그 크기가 134x100인 직사각형의 중심을 반환합니다. 예 4.3은 어떻게 메시지가 분해되며 발송되는지를 보여줍니다. 괄호안에 있는 메시지가 제일 먼저 발송됩니다: 65@325 와 134@100, 두 개의 바이너리 메시지를 포함한 괄호로 묶인 메시지가 제일 먼저 발송되며, 이어서 꼭지점들을 리턴하고, 그 다음 키워드 메시지 extent:가 발송되며, 직사각형을 반환합니다. 마지막으로 단항 메시지 center가 직사각형에 발송되며, 꼭지점이 리턴 됩니다. 괄호 없는 메시지를 분해하는 작업은 오류를 발생합니다. 그 이유는 오브젝트 100이 메시지 center를 이해하지 못하기 때문입니다.
예 4.3: 괄호 예제 | ||||
(65 @ 325 extent: 134 @ 100) center | ||||
(1) | 65@325 | "binary" | ||
⇒ aPoint | ||||
(2) | 134@100 | "binary" | ||
⇒ anotherPoint | ||||
(3) | aPoint extent: anotherPoint | "keyword" | ||
⇒ aRectangle | ||||
(4) | aRectangle center | "unary" | ||
⇒ 132@375 |
왼쪽에서 오른쪽으로
이제 우리는 다양한 종류의 메시지와 우선권이 취급되는 방식을 알게 되었습니다. 제기되어야 할 마지막 질문은, 동일한 우선권을 가진 메시지가 어떤 순서로 발송될까? 입니다. 동일한 우선권을 가진 메시지들은 왼쪽에서 오른쪽 순서로 발송됩니다. 예시 4.3에서 여러분이 두 개의 꼭지점 생성 메시지 (@)가 다른 것보다 먼저 발송되었던 것을 보셨던 것을 상기해 주십시오.
Exmaple. 메시지 보내기 Pen new down 모든 메시지는 단항 메시지이므로, 가장 왼쪽의 Pen new가 가장 먼저 발송됩니다. 이것은 그림 4.6에서 보이는 것 처럼, 두 번째 메시지 down 이 발송된 새롭게 만들어진 Pen을 리턴합니다.
그림 4.6: Pen new down 분해하기 |
산술적 비일관성
메시지 작성 규칙들은 단순하지만, 바이너리 메시지로 표현된 산술적 메시지 보내기의 실행에 있어 비일관성을 유발합니다. 여기서, 우리는 괄호가 필요한 일반적인 상황들에 대해 알아볼 것입니다.
3+4*5 | ⇒ 35 "(not 23) 왼쪽에서 오른쪽으로 이항 메시지를 보냈습니다" |
3 + (4 * 5) | ⇒ 23 |
1 + 1/3 | ⇒ (2/3) "and not 4/3" |
1 + (1/3) | ⇒ (4/3) |
1/3 + 2/3 | ⇒ (7/9) "and not 1" |
(1/3) + (2/3) | ⇒ (7/9) |
Exmaple. 메시지 보내기 20+2 * 5에서, 바이너리 메시지는 +와 * 뿐 입니다. 그럼에도 불구하고, 스몰토크에서는 연산 +와 *를 위한 특정 우선권은 존재하지 않습니다. 이것들은 단지 바이너리 메시지 이므로, *는 +에 우선권을 갖지 않습니다. 예시 4.4에서 보이듯이, 여기서는 제일 왼쪽의 +가 발송되었으며 (1) 그 다음 *가 결과에 발송되었습니다.
예시 4.4: 20+2*5 분해하기 | |
"바이너리 메시지들 사이에 우선권이 존재하지 않듯이, 제일 왼쪽의 메시지 +는 , 산술적 규칙 *가 첫 번째로 발송되어야 함에도 불구하고, 첫 번째로 평가됩니다" | |
20 + 2 * 5 | |
(1) | 20 + 2 ⇒ 22 |
(2) | 2 * 5 ⇒ 110 |
그림 4.4에서 보이듯이, 이 메시지 보내기의 결과는 30이 아니며 110입니다. 이 결과는 아마도 기대하지 못했던 것이지만, 메시지를 보내기 위해 사용된 규칙을 직접 따른 것입니다.
그림 4.7 괄호를 사용하는 등가 메시지 |
괄호사용은 스몰토크 모델의 단순성을 위해 어느 정도 들일 필요가 있는 수고입니다.
우리는 정확한 결과를 얻기 위해, 괄호를 사용해야만 합니다. 메시지에 괄호를 넣으면, 첫 번째로 평가됩니다. 그러므로 메시지 보내기 20+(2*5)는 예시 4.5에서 보이는 것과 같은 결과를 리턴합니다.
예시 4.5: 20+(2*5) 분해하기 | ||
"괄호로 싸인 메시지가 처음으로 평가되며, 그러므로 *는 정확한 동작을 유발하는 + 이전에 전송됩니다" | ||
20 + | (2 * 5) | |
(1) | (2 * 5) ⇒ 10 | |
(2) | 20 + | 10 ⇒ 30 |
스몰토크에서는 연산 +와 * 와 같은 산술 연산자는 다른 우선권을 갖지 않습니다.
+와 *는 단지 바이너리 메시지일 뿐이므로, *는 +에 대해 우선권을 갖지 않습니다.
원하는 결과를 얻기 위해 괄호를 사용합니다.
첫 번째 규칙이 바이너리 메시지와 키워드 메시지 이전에 발송된 단항 메시지는 명확한 괄호 넣기를 피한다는 진술에 유의하십시오. 표 4.8은 규칙들이 존재하지 않을 경우, 규칙들과 동등한 메시지들을 따라 메시지 보내기를 작성함을 보여줍니다.
그림 4.8: 메시지 보내기와 괄호를 넣은 등가물 | |
aPen color: Color yellow | aPen color: (Color yellow) |
aPen go: 100 + 20 | aPen go: (100 + 20) |
aPen penSize: aPen penSize + 2 | aPen penSize: ((aPen penSize) + 2) |
2 factorial +4 | 2 factorial + 4 (2 factorial) + 4 |
Notes
- ↑ 사실, 비슷한 수준이지만 더 간단한 표현을 쓸 수 있습니다: Boolean methodDict select: #isAbstract thenCollect: #selector