SqueakByExample:4.3: Difference between revisions

From 흡혈양파의 번역工房
Jump to navigation Jump to search
(번역수정)
(문단구번)
Line 54: Line 54:


이제 우리가 알아보려는것은 어떤 Boolean클래스의 메서드가 추상요소인가 하는 것입니다<ref name="주석4-1">사실, 비슷한 수준으로 작성할 수 있지만 이지만 더 간단한 표현을 쓰겠습니다: Boolean methodDict select: #isAbstract thenCollect: #selector</ref>. 메서드 사전<sup>dictionary</sup>의 키를 위해, aClass 라는 인자클래스를 이 클래스의 추상메서드를 선택합니다. 그 다음, Boolean이라는 실체적인 값 에 인수 aClass 를(arugument aClass)를 바인딩합니다. 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 >> 이항 메시지를 보내는 용도로만 쓰일 괄호가 필요합니다. 결과적으로 Boolean의 실체적 하위클래스인 True와 False로 구현한 메서드를 볼 수 있습니다.
이제 우리가 알아보려는것은 어떤 Boolean클래스의 메서드가 추상요소인가 하는 것입니다<ref name="주석4-1">사실, 비슷한 수준으로 작성할 수 있지만 이지만 더 간단한 표현을 쓰겠습니다: Boolean methodDict select: #isAbstract thenCollect: #selector</ref>. 메서드 사전<sup>dictionary</sup>의 키를 위해, aClass 라는 인자클래스를 이 클래스의 추상메서드를 선택합니다. 그 다음, Boolean이라는 실체적인 값 에 인수 aClass 를(arugument aClass)를 바인딩합니다. 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 >> 이항 메시지를 보내는 용도로만 쓰일 괄호가 필요합니다. 결과적으로 Boolean의 실체적 하위클래스인 True와 False로 구현한 메서드를 볼 수 있습니다.


'''Exmaple.''' 메시지 '''aPen color: Color yellow''' 메시지는, 클래스 Color로 보내지는 단항메세지와 aPen으로 보내지는 Color: 라는 키워드 메시지를 가지고 있습니다. 예 4.1을 보면 우선순위에 의해 단항 메시지가 먼저 전달되기때문에 '''Color yellow'''가 전달됩니다(1번). 이 메시지 전달식은 보신바와 같이 메시지 '''aPen color: aColor''' 의 인수로서 전달되는 color 오브젝트입니다(2번). 그림 4.3은 어떻게 메시지가 발송되는지 그림으로 보여줍니다.
'''Exmaple.''' 메시지 '''aPen color: Color yellow''' 메시지는, 클래스 Color로 보내지는 단항메세지와 aPen으로 보내지는 Color: 라는 키워드 메시지를 가지고 있습니다. 예 4.1을 보면 우선순위에 의해 단항 메시지가 먼저 전달되기때문에 '''Color yellow'''가 전달됩니다(1번). 이 메시지 전달식은 보신바와 같이 메시지 '''aPen color: aColor''' 의 인수로서 전달되는 color 오브젝트입니다(2번). 그림 4.3은 어떻게 메시지가 발송되는지 그림으로 보여줍니다.


{| style="font-weight: bold; border: 1px solid black; background-color:#BBBBBB;"
{| style="font-weight: bold; border: 1px solid black; background-color:#BBBBBB;"
Line 70: Line 71:
|(2번)||aPen color||: 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는 메시지가 어떻게 실행되는지를 보여줍니다.
'''Example.''' 메시지 aPen go:100 + 20에서, 바이너리 메시지 +20과 키워드 메시지 go:가 있습니다. 바이너리 메시지는 키워드 메시지 전에 발송되므로, 100+20이 먼저 발송됩니다. (1): 메시지 +20은 오브젝트 100에 발송되며, 숫자 120을 리턴합니다. 그 다음, 메시지 aPen go: 120은 인수로서, 120과 함께 발송됩니다 (2). 예 4.2는 메시지가 어떻게 실행되는지를 보여줍니다.


{| style="font-weight: bold; border: 1px solid black; background-color:#BBBBBB;"
{| style="font-weight: bold; border: 1px solid black; background-color:#BBBBBB;"

Revision as of 10:01, 4 March 2013

메시지 구성하기

3종류의 메시지는, 명쾌한 방식으로 메시지가 작성될 수 있도록 해주는 각각 다른 우선순위를 가지고 있습니다.

  1. 단항 메시지는 항상 먼저 전달되며, 그 다음 바이너리 메시지이고, 마지막으로 키워드 메시지가 보내집니다.
  2. 괄호 안에 있는 메시지는 어떤 종류의 메시지 보다 먼저 보내집니다.
  3. 동일한 종류의 메시지는 왼쪽에서부터 오른쪽으로 계산됩니다.


이 규칙들은 매우 자연스러운 읽기 순서로 이어집니다. 지금, 만약 여러분이, 여러분이 원하는 순서대로 메시지가 전달되기를 원한다면, 그림 4.3에서 볼수있듯이 원하는만큼 괄호들을 추가로 사용하면 됩니다. 이 그림에서, 메시지 yellow는 단항 메시지이며, 메시지 color:는 키워드 메시지이므로, 우선순위에 의해 메시지 전송식 Color yellow 가 먼저 전달됩니다. 하지만 굳이 Color yellow 주위에(필요없는) 괄호를 넣은 것은 단지 이 메세지전송식이 먼저 보내진다는것을 강조하는 의미가 있습니다. 나머지 장에서는 이 강조할 점을 설명합니다.

그림 4.3: Color yellow 가 전달되어야 하기때문에 단항메시지(yellow)가 먼저 전송됩니다. 이 단항 메세지는 aPen color:의 메세지로 전달될 color 오브젝트를 반환합니다.


단항 > 바이너리 > 키워드

단항 메시지를 먼저보내고, 그 다음이 바이너리 메시지이며, 마지막으로 키워드 메시지가 전달됩니다. 또한 다른 종류의 메시지보다 단항 메시지가 더 높은 우선순위를 가지게 됩니다.


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]. 메서드 사전dictionary의 키를 위해, aClass 라는 인자클래스를 이 클래스의 추상메서드를 선택합니다. 그 다음, Boolean이라는 실체적인 값 에 인수 aClass 를(arugument aClass)를 바인딩합니다. 단항 메시지 isAbstract를 메서드에 보내기 전에, 클래스에서 메서드를 선택하는 >> 이항 메시지를 보내는 용도로만 쓰일 괄호가 필요합니다. 결과적으로 Boolean의 실체적 하위클래스인 True와 False로 구현한 메서드를 볼 수 있습니다.


Exmaple. 메시지 aPen color: Color yellow 메시지는, 클래스 Color로 보내지는 단항메세지와 aPen으로 보내지는 Color: 라는 키워드 메시지를 가지고 있습니다. 예 4.1을 보면 우선순위에 의해 단항 메시지가 먼저 전달되기때문에 Color yellow가 전달됩니다(1번). 이 메시지 전달식은 보신바와 같이 메시지 aPen color: aColor 의 인수로서 전달되는 color 오브젝트입니다(2번). 그림 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 "그 다음 키워드 메시지가 전달됩니다"


UKeyBinPar 01.png UunKeyBin.png
그림 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에서 여러분이 두 개의 꼭지점 생성 메시지 (@)가 다른 것보다 먼저 발송되었던 것을 보셨던 것을 상기해 주십시오.


Rule Three. 동일한 종류의 메시지가 있을 때, 평가 순서는 왼쪽에서 오른쪽 입니다.


Exmaple. 메시지 보내기 Pen new down 모든 메시지는 단항 메시지이므로, 가장 왼쪽의 Pen new가 가장 먼저 발송됩니다. 이것은 그림 4.6에서 보이는 것 처럼, 두 번째 메시지 down 이 발송된 새롭게 만들어진 Pen을 리턴합니다.


UcompoUn.png
그림 4.6: Pen new down 분해하기
UcompoNoBracketPar.png

산술적 비일관성

메시지 작성 규칙들은 단순하지만, 바이너리 메시지로 표현된 산술적 메시지 보내기의 실행에 있어 비일관성을 유발합니다. 여기서, 우리는 괄호가 필요한 일반적인 상황들에 대해 알아볼 것입니다.


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입니다. 이 결과는 아마도 기대하지 못했던 것이지만, 메시지를 보내기 위해 사용된 규칙을 직접 따른 것입니다.


UcompoNumberBracket.png
UKeyUnBinPar.png
UunKeyBinPar.png
그림 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

  1. 사실, 비슷한 수준으로 작성할 수 있지만 이지만 더 간단한 표현을 쓰겠습니다: Boolean methodDict select: #isAbstract thenCollect: #selector