SqueakByExample:2.6

From 흡혈양파의 번역工房
Revision as of 13:03, 10 January 2013 by Onionmixer (talk | contribs) (주석 오류 수정)
Jump to navigation Jump to search

SBEGame 클래스 정의하기

자 이제, SBEGame이라 부를 게임을 위해 필요한 다른 클래스를 만들겠습니다.


Squeak comment.png메인 창의 브라우저에서 보이는 클래스 정의 템플릿(the class definition template)를 만드십시오.


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


클래스 2.3: SBEGame 클래스 정의하기

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


BoderedMorph의 하위 클래스를 만들었습니다.[1] Morph는 스퀵에서 모든 그래픽 모양새에 대한 상위클래스이며 (놀랍네요!), BorderedMorph는 테두리를 가진 Morph입니다. 또한 원래대로라면 인스턴스 변수의 이름을 두 번째 줄의 따옴표 사이에 넣겠지만, 지금은 그 목록을 빈 목록으로 남겨 놓겠습니다.

자 이제 SBEGame에 대한 initialize 메서드를 정의합시다.


Squeak comment.png다음 내용을 SBEGame에 대한 메서드로 브라우저에 입력하고, 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는 실수가 아닙니다- 이것은 단지 아직 정의하지 않은 메서드이므로, 이 작업을 1-2분내에 수행할 것입니다.


Squeak comment.png그러므로 단지 메뉴에서 정말로 의미했던 cellsPerside인 첫 번째 아이템을 선택하십시오.


그 다음 - 스퀵은 셀의 의미를 모른다고 불평할 것입니다. 스퀵은 이 오류를 수정하는 여러 개의 방법을 제공합니다.


Squeak comment.pngdeclare instance를 선택하십시오. 그 이유는 셀이 인스턴스 변수로 취급하기를 원하기 때문입니다.


마지막으로, 스퀵은 마지막에 보낸 메시지 newCellAt:at에 관해 불평하겠지만, 이것은 실수가 아니므로, 그 메시지 또한 확인(confirm) 합니다.

만약 클래스 정의를 다시 한번 보았다면(instance버튼을 눌러서 할 수 있는), 인스턴스 변수 셀을 포함하기 위해 브라우저가 그 정의를 수정했다는 것을 알게 될 것입니다.

이 initialize 메서드를 보겠습니다. 이 줄 | sampleCell width height n | 은 임시로 4개의 변수를 선언합니다. 이 변수들은 임시 변수로 불리며, 그 이유는, 그 변수들의 범위와 수명이 이 initialize 메서드에 제한되어 있기 때문입니다. 설명하는듯한 이름을 가진 임시 변수는 코드를 분석하기 쉽게 만들어줍니다. 스몰토크는 상수와 변수를 구분하기 위한 특별한 문법(구문)을 갖고 있지 않으며, 사실 이 4개의 "변수"는 실제로 상수입니다. 4-7번째 줄은 이 상수들을 정의합니다.

게임판은 얼마나 커야 할까요? 몇 가지 정수 만큼의 셀을 담기에 충분히 크고, 그 셀 주위에 경계를 그리기에 충분한 커야 합니다. 얼마나 많은 셀이 적합한 숫자의 셀일까요? 5? 10? 100? 아직 그것을 모르지만, 만약 그것을 알았다면 나중에 아마도 변경을 진행하게 될 것입니다. 그러므로, 그 수(게임판을 그리기 위한 숫자)를 알기 위한 책임을 cellsPerSide라고 부를 다른 메서드에 위임하였으며, 우리는 앞으로 1-2분내에 해당 메서드를 작성할 것입니다. 그 이유는 initialize를 위해 메서드 바디(the method body)를 프로그래밍하고 Accept(저장)하는경우, 스퀵에서 지정한 이름으로 메서드를 정의하고 "확인(confirm), 수정(correct) 또는 취소(cancel)"하기 전에, 우리가 cellsPerSide 메시지를 보내고 있기 때문입니다.[2] 고민할 필요는 없습니다. 이 작업은 아직 정의되지 않은 다른 메서드에 관해서 작업을 진행하는 좋은 방법입니다. 왜 그럴까요? 글쎄요, 이 실행 방법은 initialize 메서드 작성이 필요하다는 것을 인식하고, 작성을 시작할 때까지는 좋은 진행방법이 아니었으며, 그 시점에서, 의미있는 이름을 그 실행 방법에 부여한 후 작업의 흐름을 방해하지 않고, 계속 작업을 진행하였기 때문입니다.

네번째 줄은 이 메서드를 사용합니다. 스몰토크 self cellsPerSide는 메시지 cellsPerSider를 자신에게 보냅니다. 예를 들자면, 동일한 해당 오브젝트에 보냅니다. 이에 대한 반응은, 게임판의 측면당 셀의 숫자가 되며, n에 할당됩니다.

다음의 3개의 줄은, 새로운 SBCcell 오브젝트를 만들고, 그것의 너비와 높이를 적합한 임시 변수에 할당합니다.

여덟번째의 줄은 새로운 오브젝트의 bounds를 설정합니다. 지금까지의 세부적인 내용에 대한 염려 없이, 괄호안의 표현식은 점 (5,5)에서 사각형의 원점(예를 들어 상단 왼쪽 모서리)으로 사각형을 만들고, 하단 우측 모서리는 셀의 오른쪽 숫자만큼의 공간을 허용하기 위해 충분히 떨어져 있을 것이라는 우리의 설명을 믿어주시기 바랍니다.

마지막 줄은 SBEGame 오브젝트의 인스턴스 변수 셀을 행과 열의 알맞은 숫자로, 배열을 만듭니다. 이 작업을 메시지 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 매트릭스를 만들고 그 매트릭스의 구성요소를 초기화합니다. 각 구성요소의 초기 값은 그 구성요소의 좌표(coordinates)에 기초합니다. (i,j) 구성요소룰 자체 newCellAt: i at: j. 평가의 결과로 초기화합니다.

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

만약 여러분이 more...를 좀 더 많이 사용한다는 것을 아셨다면 more...를 직접 불러오기 위해 마우스 버튼을 클릭할 때 Shift키를 누르고 있을 수 있습니다.

Notes

  1. Package라는것은 이럴때 유용합니다. 여러개의 Class를 하나로 묶는거죠. 즉 부모class가 서로 다른 여러개의 Class를 같은 패키지로 묶어서 라이브러리처럼 관리하게 됩니다
  2. 코드를 작성하며 정의되지 않은 selector를 신경쓰지 않고 계속 작업을 진행하는 부분입니다. 번역을 하니 말이 좀 어렵네요.