SqueakByExample:2.6: Difference between revisions

From 흡혈양파의 번역工房
Jump to navigation Jump to search
mNo edit summary
(검수 20180719)
 
(37 intermediate revisions by the same user not shown)
Line 1: Line 1:
==클래스 SBEGame을 정의하기==
==SBEGame 클래스 정의하기==


이제, '''SBEGame'''이라 부를 게임을 위해 우리가 필요한 다른 클래스를 만들겠습니다.  
이제 '''SBEGame''' 이라고 이름붙일 게임에 필요한 다른 클래스를 만들어보도록 하겠습니다.




{{CommentSqueak|메인 창의 브라우저에서 보이는 클래스 정의 템플릿(the class definition template)를 만듭니다.}}
{{CommentSqueak|브라우저 메인 창에서 클래스 정의 템플릿을 보이게 하십시오.}}




이미 선택한 클래스 카테고리의 이름을 두 번 클릭하거나 {{HighlightBold|SBECell}}을 정의를 다시 표시함으로써({{Template:HighlightBox|instance}} 버튼을 클릭하여)이 작업을 수행합니다. 다음과 같이 읽을 수 있도록 코드를 편집하고 {{Template:HighlightGray|accept}} 합니다.
이미 선택한 클래스 카테고리의 이름을 두 번 클릭하거나, ({{Template:HighlightBox|instance}} 버튼을 클릭하여){{HighlightBold|SBECell}}의 정의를 보이게 하십시오. 다음과 같이 코드를 편집하고 {{Template:HighlightGray|accept}} 하십시오.




클래스 2.3: SBEGame 클래스 정의하기
클래스 2.3: SBEGame 클래스 정의
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
BorderedMorph subclass: #SBEGame                                                                             
BorderedMorph subclass: #SBEGame                                                                             
Line 16: Line 16:
classVariableNames: ''                                                                                         
classVariableNames: ''                                                                                         
poolDictionaries: ''                                                                                           
poolDictionaries: ''                                                                                           
category: 'SBE--Quinto'
category: 'SBE-Quinto'
</syntaxhighlight>
</syntaxhighlight>




여기에 우리는 BoderedMorph를 하위분류하였습니다; 모프(Morph)스퀵에서 모든 그래픽 문양의 수퍼클래스 이며 그리고 BorderedMorph는 경계를 가진 모프(Morph)입니다. 우리는 또한 인스턴스 변수의 이름을 두 번째 라인의 따옴표 사이에 삽입할 것이지만, 지금은 그 목록을 빈 목록으로 남겨 놓겠습니다.  
이제 BoderedMorph의 하위클래스를 만들 차례입니다.<ref name="역자주1">Package 는 이럴 때 유용합니다. 여러 개의 클래스를 하나로 묶어둡니다. 각각의 상위클래스가 서로 다른 여러개의 클래스를 같은 패키지로 묶어서 라이브러리처럼 관리합니다</ref> Morph 는 스퀵의 모든 그래픽 도형에 대한 상위클래스가 되며(놀랍군요!), BorderedMorph 는 테두리를 가진 Morph 입니다. 두번째 줄의 따옴표 사이에 인스턴스 변수의 이름을 넣을 수도 있겠지만, 지금은 그냥 빈 목록으로 남겨 놓겠습니다.  


자 이제 SBEGame을 위해 초기화 메서드(initialize method)를 정의합시다.  
자 이제 SBEGame에 대한 initialize 메서드를 정의하도록 하겠습니다.  




{{CommentSqueak|다음 내용을 {{HighlightBold|SBEGame}}을 위한 메서드로서 브라우저에 타이핑하고, {{Template:HighlightGray|accept}} 를 실행합니다.}}
{{CommentSqueak|{{HighlightBold|SBEGame}}에 대한 메서드를 브라우저에 다음과 같이 입력하고, {{Template:HighlightGray|accept}} 해보십시오:}}




메서드 2.4: 게임 초기화하기
메서드 2.4: 게임 초기화
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
initialize
initialize
| sampleCell width height n |
  | sampleCell width height n |
super initialize.
  super initialize.
n := self cellsPerSide.
  n := self cellsPerSide.
sampleCell := SBECell new.
  sampleCell := SBECell new.
width := sampleCell width.
  width := sampleCell width.
height := sampleCell height.
  height := sampleCell height.
self bounds: (5@5 extent: ((width*n) @(height*n)) + (2 * self borderWidth)).
  self bounds: (5@5 extent: ((width*n) @(height*n)) + (2 * self borderWidth)).
cells := Matrix new: n tabulate: [ :i :j | self newCellAt: i at: j ].
  cells := Matrix new: n tabulate: [ :i :j | self newCellAt: i at: j ].
</syntaxhighlight>
</syntaxhighlight>




스퀵은 용어들 중 몇 가지의 의미를 모른다고 불평할 것입니다. 스퀵은 여러분에게 메시지 CellsPerSide를 모른다고 말할 것이며, 여러 수정을 가한 용어들을 제시할 것입니다. 그러할 경우, 여러분의 스펠링 실수가 있었던 것입니다.  
스퀵은 일부 용어의 의미를 모른다고 불평할 것입니다. 스퀵은 CellsPerSide 메시지를 모른다고 것이며, 대신하기 위한 수많은 컬렉션을 제안할텐데, 이 경우에는 철자 오류가 있습니다.




Line 49: Line 49:
|[[image:UnknownSelector.png]]||[[image:DeclareInstanceVar.png]]
|[[image:UnknownSelector.png]]||[[image:DeclareInstanceVar.png]]
|- style="text-align: center;"
|- style="text-align: center;"
|그림 2.8 알려지지 않은 selector를 감지한 스퀵||그림 2.9: 새로운 인스턴스 변수 공표하기
|그림 2.8 알려지지 않은 selector를 감지한 스퀵||그림 2.9: 새로운 인스턴스 변수 선언하기
|}
|}




그러나 '''cellsPerSide'''는 실수가 아닙니다- 이것은 단지 우리가 아직 정의하지 않은 메서드이므로, 우리는 이 작업을 1-2분내에 수행할 것입니다.
하지만 '''cellsPerSide''' 는 잘못 입력한 것이 아닙니다. ---아직 정의하지 않은 메서드일 뿐입니다--- 짧은 시간 안에 메서드를 정의해보겠습니다.




{{CommentSqueak|그러므로 단지 메뉴에서 우리가 정말로 의미했던 {{HighlightBold|cellsPerside}}인 첫 번째 아이템을 선택합니다.}}
{{CommentSqueak|메뉴에서 첫 번째 항목을 선택하면 {{HighlightBold|cellsPerside}} 를 실제로 의미했음을 확인할 수 있습니다.}}




그 다음ㅡ 스퀵은 셀의 의미를 모른다고 불평할 것입니다. 스퀵은 이 오류를 수정하는 여러 개의 방법을 여러분에게 제공합니다.  
다음차례로, 스퀵은 cells 의 의미를 모른다고 불평할 것입니다. 이런 문제를 수정하기 위한 수많은 방법이 제공됩니다.




{{CommentSqueak|{{HighlightGray|declare instance}}를 선택합니다. 그 이유는 우리는 셀이 인스턴스 변수(instance variable)가 되기를 원하기 때문입니다.}}
{{CommentSqueak|cells 를 인스턴스 변수로 만들 것이므로, {{HighlightGray|declare instance}} 를 선택하십시오.}}




마지막으로, 스퀵은 우리가 마지막에 보낸 메시지 newCellAt:at에 관해 불평할 것이지만, 이것은 실수가 아니므로, 그 메시지 또한 확인(confirm) 합니다.
마지막으로, 스퀵은 마지막 줄에서 보낸 newCellAt:at: 메시지에 대해 불평할 것입니다. 이것도 실수가 아니기 때문에 메시지를 확인하기 바랍니다.


만약 여러분이 클래스 정의(the class definition)을 다시 한번 보았다면({{Template:HighlightBox|instance}}버튼을 누름으로서 할 있는), 인스턴스 변수 셀을(the instance variable cells)포함하기 위해 브라우저가 그 정의를 수정했다는 것을 알게 될 것입니다.
클래스 정의를 다시 한 번 살펴보면({{Template:HighlightBox|instance}} 버튼을 클릭하면 실행할 있음), Browser 가 인스턴스 변수인 cells 를 포함하도록 클래스의 정의를 수정<ref name="역자주2">Class가 정의된 부분을 보면 instanceValirableNames 부분에 cells가 추가된것을 확인할 수 있습니다</ref>했다는 것을 알 수 있습니다.


이 초기화 메서드(initialize method)를 보겠습니다. 이 라인 '''| sampleCell width height n |''' 은 4개의 임시 변수(temporary variables)를 공표합니다. 그 변수들은 임시 변수로 불리며, 그 이유는, 그 변수들의 범위(scope)와 수명(life time)이 이 초기화 메서드에 제한되어있기 때문입니다. 설명하는 이름을 가진 임시 변수는 코드를 좀더 읽기 쉽게 만드는 작업에 유익합니다. 스몰토크는 상수(constant)와 변수(variables)를 구분하기 위한 특별한 구문(syntax)을 갖고 있지 않으며, 사실 이 4개의 “변수”는 실제로 상수입니다. 4-7라인은 이 상수들을 정의합니다.


우리의 게임 보드는 얼마나 커야 할까요? 몇몇 진정수(眞整數,integral number)만큼의 셀을 담기에 충분히 크고, 그 셀 주위에 경계를 그리기에 충분한 커야 합니다. 얼마나 많은 셀이 적합한 숫자의 셀일까요? 5? 10? 100? 우리는 아직 그것을 모르며 만약 그것을 알았다면, 나중에 우리의 마음을 아마도 바꾸었을 것입니다. 그러므로, 그 수를 알기 위한 책임을 우리가 cellsPerSide라고 부를 다른 메서드에 위임하였으며, 우리는 1-2분내에 그 메서드를 작성할 것입니다. 그 이유는 우리가 초기화(initialize)를 위해 메서드 바디(the method body)를 수락할 때, 스퀵은 우리에게 "확인(confirm), 수정(correct) 또는 취소(cancel)"할 것을 질문한 이름으로 우리가 메서드를 정의하기 전에, 우리는 cellsPerSide 메시지를 보내고 있기 때문입니다. 이 작업을 망설이지 마십시오. 이 작업은 우리가 아직 정의하지 않은 다른 메서드에 관해서 작성해야 할 좋은 실행법입니다. 왜 그럴까요?  글쎄요, 이 실행법은 우리가 초기화 메서드 작성이 필요하다는 것을 인식하고, 작성을 시작할 때까지 좋은 실행법이 아니었고, 그 시점에서, 우리는 의미있는 이름을 그 실행법에 부여한 후 우리의 작업흐름을 방해하지 않고, 계속 작업을 진행하였기 때문입니다.
이제 initialize 메서드를 살펴 보겠습니다. '''| sampleCell width height n |''' 줄에서는 임시로 4개의 변수를 선언합니다. 변수의 범위와 수명이 메서드에 국한되기 때문에 임시 변수<sup>temporary variables</sup>라고 부르도록 하겠습니다. 설명이 잘 되어있는 이름이 붙은 임시 변수는 코드 가독성을 더 좋게 하는데 도움이 됩니다. Smalltalk 에는 상수와 변수를 구분하기 위한 특별한 문법이 없으며, 사실 이 네 개의 모든"변수<sup>“variables”</sup>"는 사실 상수입니다. 4-7 번째 줄은 이들 상수를 정의합니다.


4 번째의 라인은 이 메서드를 사용합니다. 스몰토크 self cellsPerSide는 메시지 cellsPerSider를 이 그 자신에게 보냅니다. 예를 들어, 바로 그 오브젝트에 보냅니다(i.e., to this very object). 이에 대한 반응은, 게임 보드의 측면당 셀의 숫자가 되며, n에 할당됩니다.


다음의 3개의 라인은, 새로운 SBCcell 오브젝트를 만들고, 그것의 너비와 높이를 적합한 임시 변수에 할당합니다.  
게임판은 얼마나 커야 할까요? 몇몇 정수 크기만큼의 cell 을 담기에 충분히 크고, 그 cell 주위에 경계를 그리기에 충분할만큼 커야 합니다. cell 의 갯수는 얼마정도가 적당할까요? 5? 10? 100? 아직은 모르지만, 이미 알고 있다고 해도, 나중에 변경하게 될지 모르겠군요. 그렇기 때문에, 이러한 숫자를 알아야 하는 책임을 다른 메서드로 위임하려 합니다. 이 메서드는 cellsPerSide 라는 이름을 가지며, 1~2 분 사이에 작성하려 합니다.


8번째의 라인은 새로운 오브젝트의 bounds를 설정합니다. 지금까지의 세부적인 내용에 대한 염려 없이, 괄호안의 표현식은 점 (5,5)에서 사각형의 원점(예를 들어 상단 왼쪽 모서리)으로 사각형을 만들고, 하단 우측 모서리는 셀의 오른쪽 숫자만큼의 공간을 허용하기 위해 충분히 떨어져 있을 것이라는 우리의 설명을 믿어주십시오.
initialize 메서드에 대한 내용을 accept 했을 때, "확인(confirm), 수정(correct) 또는 취소(cancel)" 를 물어보는 다이얼로그가 뜨게되는데, 이런 현상은 스퀵이 요청한 이름을 가진 메서드가 정의되지도 않았을때, cellsPerSide 라는 메시지를 보내기 때문입니다. 걱정하지 마세요. 이런 방법은 아직 정의되지 않은 다른 메서드로 작업을 진행하는 좋은 방법입니다. 왜 일까요? 글쎄요, initialize 메서드를 작성하기 전에 먼저 필요성을 느낀것도 아니기 때문에, 상황이 발생되었을때 의미있는 이름을 부여하고 작업의 흐름을 방해하지 않고 작업을 계속 진행할 수 있습니다.


마지막 라인은 '''SBEGame''' 오브젝트의 인스턴스 변수 셀을 행과 열의 알맞은 숫자로, 매트릭스를(matrix) 만듭니다. 우리는 이 작업을 메시지 '''new:tabulate'''를 매트릭스 클래스(오브젝트이기도 한 클래스이므로, 우리는 그 클래스에 오브젝트를 보낼 수 있습니다)에 보냄으로써 수행합니다. 우리는 '''new:tabulate'''가 두개의 인수를 취한다는 것을 알고 있으며, 그 이유는 그것이 두 개의 콜론(:)을 그 이름에 갖고 있기 때문입니다. 인수는 콜론 바로 뒤에 옵니다. 만약 여러분이 인수를 모두 괄호 안에 넣는 언어를 사용해 왔었다면, 이 표기법이 매우 이상하게 느껴질 것입니다. 당황해 하지 마십시오, 이것은 단지 구문(syntax)일 뿐입니다. 이 구문은, 메서드의 이름이 인수의 역할을 설명하기 위해 사용되었으므로, 매우 좋은 구문인 것으로 밝혀졌습니다. 예를 들면, '''Matrix rows: 5 columns: 2''' 는 5개의 가로열과 2개의 새로열을 갖는 것이지 2개의 가로열과 5개의 세로행을 가진 것이 아닙니다.


'''Matrix n tabulate: [ :i :j | self newCellAt: i at: j ]''' 은 새로운 n x n 매트릭스를 만들고 그 매트릭스의 구성요소를 초기화합니다. 각 구성요소의 초기 값은 그 구성요소의 좌표(coordinates)에 기초합니다. (i,j) 구성요소는 자체 newCellAt: i at: j. 평가의 결과로 초기화 됩니다.  
네번째 줄은 이렇게 정의된 cellsPerSide 메서드를 사용합니다. 스몰토크에서 self cellsPerSide 는 cellsPerSide 메시지를 나 자신(SBEGame)을 의미하는 객체인 self 에 보냅니다. 게임판의 각 모서리당 cell 의 갯수 응답을 n 에 할당합니다.
 
 
그 다음의 세 줄에서는, 새로운 SBECell 객체를 만들고, 객체의 너비와 높이를 적당한 임시 변수에 넣습니다.
 
 
여덟번째 줄은 새로운 객체의 bounds 를 설정합니다. 세부적인 내용에 대한것은 걱정할 필요가 없으며, 괄호 안에 있는 표현이 point (5,5) 와 그 하단 오른쪽 모서리에 원점<sup>orign</sup>을 둔 정사각형(즉, 왼쪽 위)을 만든다고 믿으십시오. 적절한 개수의 cell 이 있는 공간을 허용하려는 목적에 맞게 충분하게 멀리 떨어져 있습니다.
 
 
마지막 줄은 '''SBEGame''' 객체의 인스턴스 변수인 cells 에 올바른 행과 열의 개수대로 새로 만든 ''Matrix'' 를 할당합니다. Matrix 클래스(클래스도 객체이므로, 메시지를 보낼 수 있습니다)에  '''new:tabulate:''' 메시지를 보내서 처리했습니다. new:tabulate: 의 이름에 두 개의 콜론(:)이 있는걸 보면, 이 메서드는 인자를 두 개 받는다는걸 알 수 있습니다. 인자는 콜론 바로 다음에 위치하게 됩니다. 만약 당신이 인자를 모두 괄호 안에 넣는 프로그래밍 언어를 사용해 왔었다면, 이 표기법은 매우 이상하게 느껴질 것입니다. 당황하지 마세요, 이것은 단지 문법일 뿐입니다! 이런 방법은 메서드의 이름으로 인자의 역할을 설명하는데 활용할 수 있기 때문에, 상당히 좋은 문법으로 알려져 있습니다. 예를 들어, '''Matrix rows: 5 columns: 2''' 는 5개의 가로 열과 2개의 세로 열을 갖는 것이지 2개의 가로 열과 5개의 세로 행을 가진 것이 아니라는 점을 확실히 알게 해줍니다.
 
 
'''Matrix n tabulate: [ :i :j | self newCellAt: i at: j ]''' 은 새로운 n x n 2차원 배열을 만들고 요소를 초기화합니다. 각각의 초기 값은 좌표에 따라 다릅니다. (i,j)번째 요소는 newCellAt: i at: j. 처리 결과로 초기화합니다.
 
지금까지의 내용이 바로 '''initialize''' 입니다. 이 메시지 내용을 accept 하면, 아마도 작성한 코드를 가지런히 다듬고(pretty-up formating) 싶을 것입니다. 직접 일일히 할 필요는 없고, 노랑-버튼 메뉴에서, {{Template:HighlightGray|more▷prettyprint}}를 선택하면, 사용자를 위해 브라우저가 알아서 해줄 것입니다. 메서드를 깔끔하게 출력하고 난 후에, 다시 {{Template:HighlightGray|accept}} 하거나, 결과가 맘에 들지 않으면 물론 취소 (CMD-l 숫자 1이 아닌 L의 소문자입니다)할 수 있습니다. 대신, 코드가 보일때는 언제나 pretty-printer 를 브라우저가 사용하도록 설정할 수도 있습니다. 보이는 것을 조절하려면 버튼 표시줄에서 가장 오른쪽 버튼을 사용하십시오.
 
 
{{Template:HighlightGray|more...}} 를 더 많이 사용하신다면, {{Template:HighlightGray|more...}} 를 직접 불러오려고 클릭할 때 Shift 키를 누른 채로 클릭하면 그 상태가 유지된다는 것을 알고 계시는 것이 좋습니다.


그것이 '''initialize(초기화)''' 입니다. 여러분이 이 메시지 바디를 수락하면, 아마도 포맷 작업을 아름답게 꾸밀 수 있는 기회를 갖기를 원하실 것입니다. 직접 그렇게 할 필요는 없으며, 노랑-버튼 메뉴에서, {{Template:HighlightGray|more▷prettyprint}}를 선택하면, 브라우저가 여러분을 위해 그 작업을 실행할 것입니다. 여러분이 pretty-printed 메서드를 갖은 후에, 다시 {{Template:HighlightGray|accept}} 하거나 또는 결과가 맘에 들지 않으면, 물론 취소를 할 수 있습니다. (CMD-l 숫자 1이 아닌 L의 소문자) 대안적으로, 여러분은 예쁜 프린터(the pretty-printer)를 자동으로 사용하기 위해, 브라우저가 코드를 보여줄 때마다 그 브라우저를 설정할 수 있습니다:  뷰를 조정하기 위해 버튼 바 에서 오른쪽 마우스 버튼을 사용할 수 있습니다.


만약 여러분이 {{Template:HighlightGray|more...}}를 좀더 많이 사용한다는 것을 인식하셨다면 {{Template:HighlightGray|more...}}를 직접 불러오기 위해 마우스 버튼을 클릭할 때 SHIFT키를 누르고 있을 수 있습니다.


==Notes==
==Notes==

Latest revision as of 15:06, 18 July 2018

SBEGame 클래스 정의하기

이제 SBEGame 이라고 이름붙일 게임에 필요한 다른 클래스를 만들어보도록 하겠습니다.


Squeak comment.png브라우저 메인 창에서 클래스 정의 템플릿을 보이게 하십시오.


이미 선택한 클래스 카테고리의 이름을 두 번 클릭하거나, (instance 버튼을 클릭하여)SBECell의 정의를 보이게 하십시오. 다음과 같이 코드를 편집하고 accept 하십시오.


클래스 2.3: SBEGame 클래스 정의

BorderedMorph subclass: #SBEGame                                                                            
instanceVariableNames: ''                                                                                      
classVariableNames: ''                                                                                        
poolDictionaries: ''                                                                                           
category: 'SBE-Quinto'


이제 BoderedMorph의 하위클래스를 만들 차례입니다.[1] Morph 는 스퀵의 모든 그래픽 도형에 대한 상위클래스가 되며(놀랍군요!), BorderedMorph 는 테두리를 가진 Morph 입니다. 두번째 줄의 따옴표 사이에 인스턴스 변수의 이름을 넣을 수도 있겠지만, 지금은 그냥 빈 목록으로 남겨 놓겠습니다.

자 이제 SBEGame에 대한 initialize 메서드를 정의하도록 하겠습니다.


Squeak comment.pngSBEGame에 대한 메서드를 브라우저에 다음과 같이 입력하고, accept 해보십시오:


메서드 2.4: 게임 초기화

initialize
  | sampleCell width height n |
  super initialize.
  n := self cellsPerSide.
  sampleCell := SBECell new.
  width := sampleCell width.
  height := sampleCell height.
  self bounds: (5@5 extent: ((width*n) @(height*n)) + (2 * self borderWidth)).
  cells := Matrix new: n tabulate: [ :i :j | self newCellAt: i at: j ].


스퀵은 일부 용어의 의미를 모른다고 불평할 것입니다. 스퀵은 CellsPerSide 메시지를 모른다고 할 것이며, 대신하기 위한 수많은 컬렉션을 제안할텐데, 이 경우에는 철자 오류가 있습니다.


UnknownSelector.png DeclareInstanceVar.png
그림 2.8 알려지지 않은 selector를 감지한 스퀵 그림 2.9: 새로운 인스턴스 변수 선언하기


하지만 cellsPerSide 는 잘못 입력한 것이 아닙니다. ---아직 정의하지 않은 메서드일 뿐입니다--- 짧은 시간 안에 메서드를 정의해보겠습니다.


Squeak comment.png메뉴에서 첫 번째 항목을 선택하면 cellsPerside 를 실제로 의미했음을 확인할 수 있습니다.


다음차례로, 스퀵은 cells 의 의미를 모른다고 불평할 것입니다. 이런 문제를 수정하기 위한 수많은 방법이 제공됩니다.


Squeak comment.pngcells 를 인스턴스 변수로 만들 것이므로, declare instance 를 선택하십시오.


마지막으로, 스퀵은 마지막 줄에서 보낸 newCellAt:at: 메시지에 대해 불평할 것입니다. 이것도 실수가 아니기 때문에 메시지를 확인하기 바랍니다.

클래스 정의를 다시 한 번 살펴보면(instance 버튼을 클릭하면 실행할 수 있음), Browser 가 인스턴스 변수인 cells 를 포함하도록 클래스의 정의를 수정[2]했다는 것을 알 수 있습니다.


이제 initialize 메서드를 살펴 보겠습니다. | sampleCell width height n | 줄에서는 임시로 4개의 변수를 선언합니다. 변수의 범위와 수명이 메서드에 국한되기 때문에 임시 변수temporary variables라고 부르도록 하겠습니다. 설명이 잘 되어있는 이름이 붙은 임시 변수는 코드 가독성을 더 좋게 하는데 도움이 됩니다. Smalltalk 에는 상수와 변수를 구분하기 위한 특별한 문법이 없으며, 사실 이 네 개의 모든"변수“variables”"는 사실 상수입니다. 4-7 번째 줄은 이들 상수를 정의합니다.


게임판은 얼마나 커야 할까요? 몇몇 정수 크기만큼의 cell 을 담기에 충분히 크고, 그 cell 주위에 경계를 그리기에 충분할만큼 커야 합니다. cell 의 갯수는 얼마정도가 적당할까요? 5? 10? 100? 아직은 모르지만, 이미 알고 있다고 해도, 나중에 변경하게 될지 모르겠군요. 그렇기 때문에, 이러한 숫자를 알아야 하는 책임을 다른 메서드로 위임하려 합니다. 이 메서드는 cellsPerSide 라는 이름을 가지며, 1~2 분 사이에 작성하려 합니다.

initialize 메서드에 대한 내용을 accept 했을 때, "확인(confirm), 수정(correct) 또는 취소(cancel)" 를 물어보는 다이얼로그가 뜨게되는데, 이런 현상은 스퀵이 요청한 이름을 가진 메서드가 정의되지도 않았을때, cellsPerSide 라는 메시지를 보내기 때문입니다. 걱정하지 마세요. 이런 방법은 아직 정의되지 않은 다른 메서드로 작업을 진행하는 좋은 방법입니다. 왜 일까요? 글쎄요, initialize 메서드를 작성하기 전에 먼저 필요성을 느낀것도 아니기 때문에, 상황이 발생되었을때 의미있는 이름을 부여하고 작업의 흐름을 방해하지 않고 작업을 계속 진행할 수 있습니다.


네번째 줄은 이렇게 정의된 cellsPerSide 메서드를 사용합니다. 스몰토크에서 self cellsPerSide 는 cellsPerSide 메시지를 나 자신(SBEGame)을 의미하는 객체인 self 에 보냅니다. 게임판의 각 모서리당 cell 의 갯수 응답을 n 에 할당합니다.


그 다음의 세 줄에서는, 새로운 SBECell 객체를 만들고, 객체의 너비와 높이를 적당한 임시 변수에 넣습니다.


여덟번째 줄은 새로운 객체의 bounds 를 설정합니다. 세부적인 내용에 대한것은 걱정할 필요가 없으며, 괄호 안에 있는 표현이 point (5,5) 와 그 하단 오른쪽 모서리에 원점orign을 둔 정사각형(즉, 왼쪽 위)을 만든다고 믿으십시오. 적절한 개수의 cell 이 있는 공간을 허용하려는 목적에 맞게 충분하게 멀리 떨어져 있습니다.


마지막 줄은 SBEGame 객체의 인스턴스 변수인 cells 에 올바른 행과 열의 개수대로 새로 만든 Matrix 를 할당합니다. Matrix 클래스(클래스도 객체이므로, 메시지를 보낼 수 있습니다)에 new:tabulate: 메시지를 보내서 처리했습니다. new:tabulate: 의 이름에 두 개의 콜론(:)이 있는걸 보면, 이 메서드는 인자를 두 개 받는다는걸 알 수 있습니다. 인자는 콜론 바로 다음에 위치하게 됩니다. 만약 당신이 인자를 모두 괄호 안에 넣는 프로그래밍 언어를 사용해 왔었다면, 이 표기법은 매우 이상하게 느껴질 것입니다. 당황하지 마세요, 이것은 단지 문법일 뿐입니다! 이런 방법은 메서드의 이름으로 인자의 역할을 설명하는데 활용할 수 있기 때문에, 상당히 좋은 문법으로 알려져 있습니다. 예를 들어, Matrix rows: 5 columns: 2 는 5개의 가로 열과 2개의 세로 열을 갖는 것이지 2개의 가로 열과 5개의 세로 행을 가진 것이 아니라는 점을 확실히 알게 해줍니다.


Matrix n tabulate: [ :i :j | self newCellAt: i at: j ] 은 새로운 n x n 2차원 배열을 만들고 요소를 초기화합니다. 각각의 초기 값은 좌표에 따라 다릅니다. (i,j)번째 요소는 newCellAt: i at: j. 처리 결과로 초기화합니다.

지금까지의 내용이 바로 initialize 입니다. 이 메시지 내용을 accept 하면, 아마도 작성한 코드를 가지런히 다듬고(pretty-up formating) 싶을 것입니다. 직접 일일히 할 필요는 없고, 노랑-버튼 메뉴에서, more▷prettyprint를 선택하면, 사용자를 위해 브라우저가 알아서 해줄 것입니다. 메서드를 깔끔하게 출력하고 난 후에, 다시 accept 하거나, 결과가 맘에 들지 않으면 물론 취소 (CMD-l 숫자 1이 아닌 L의 소문자입니다)할 수 있습니다. 대신, 코드가 보일때는 언제나 pretty-printer 를 브라우저가 사용하도록 설정할 수도 있습니다. 보이는 것을 조절하려면 버튼 표시줄에서 가장 오른쪽 버튼을 사용하십시오.


more... 를 더 많이 사용하신다면, more... 를 직접 불러오려고 클릭할 때 Shift 키를 누른 채로 클릭하면 그 상태가 유지된다는 것을 알고 계시는 것이 좋습니다.


Notes

  1. Package 는 이럴 때 유용합니다. 여러 개의 클래스를 하나로 묶어둡니다. 각각의 상위클래스가 서로 다른 여러개의 클래스를 같은 패키지로 묶어서 라이브러리처럼 관리합니다
  2. Class가 정의된 부분을 보면 instanceValirableNames 부분에 cells가 추가된것을 확인할 수 있습니다