SqueakByExample:2.6: Difference between revisions

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


게임판은 얼마나 커야 할까요? 몇 가지 정수 만큼의 칸을 담기에 충분히 크고, 그 칸 주위에 경계를 그리기에 충분한 커야 합니다. 칸 갯수는 얼마가 적당할까요? 5? 10? 100? 아직은 모르지만, 이미 알고 있었다면 나중에 바꿀지도 모릅니다. 그러므로, cellsPerSide라고 하는 다른 메서드로 숫자를 알려줄 책임을 부여하고 잠시동안 이대로 작성하도록 하겠습니다.
게임판은 얼마나 커야 할까요? 몇 가지 정수 만큼의 칸을 담기에 충분히 크고, 그 칸 주위에 경계를 그리기에 충분한 커야 합니다. 칸 갯수는 얼마가 적당할까요? 5? 10? 100? 아직은 모르지만, 이미 알고 있었다면 나중에 바꿀지도 모릅니다. 그러므로, cellsPerSide라고 하는 다른 메서드로 숫자를 알려줄 책임을 부여하고 잠시동안 이대로 작성하도록 하겠습니다.
initialize에 대한 메서드 내용을 accept 했을 때, "확인(confirm), 수정(correct) 또는 취소(cancel)" 를 물어보는 다이얼로그가 뜨게되는데 이것은 스퀵이 요청한 이름을 가진 메서드가 정의되기 이전에, cellsPerSide라는메시지를 보내기 때문입니다. 걱정하지 마십시오. 사실 아직 정의하지 않은 다른 메서드를 가지고 작업을 진행하는 좋은 방법입니다. 왜일까요? 글쎄요, 우리가 이것이 필요하다고 깨달은 시점은 initialize 작성을 시작하기 전의 상황은 아니며, 지금 알았다고 해도 현재의 작업의 흐름을 방해하지 않으면서 의미있는 이름을 부여하고 옮길 수 있기 때문입니다.
initialize에 대한 메서드 내용을 accept 했을 때, "확인(confirm), 수정(correct) 또는 취소(cancel)" 를 물어보는 다이얼로그가 뜨게되는데 이것은 스퀵이 요청한 이름을 가진 메서드가 정의되기 이전에, cellsPerSide라는메시지를 보내기 때문입니다. 걱정하지 마십시오. 사실 이런 방법은 아직 정의하지 않은 다른 메서드를 가지고 작업을 진행하는 좋은 방법입니다. 왜일까요? 글쎄요, 우리가 이것이 필요하다고 깨달은 시점은 initialize 작성을 시작하기 전의 상황은 아니며, 지금 알았다고 해도 현재의 작업의 흐름을 방해하지 않으면서 의미있는 이름을 부여하고 옮길 수 있기 때문입니다.





Revision as of 15:19, 19 February 2013

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 버튼을 클릭하면 실행할 수 있음), 인스턴스 변수 cells를 포함하기 위해 브라우저가 변수의 정의를 적용[2]했다는 것을 알게 될 것입니다.


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


게임판은 얼마나 커야 할까요? 몇 가지 정수 만큼의 칸을 담기에 충분히 크고, 그 칸 주위에 경계를 그리기에 충분한 커야 합니다. 칸 갯수는 얼마가 적당할까요? 5? 10? 100? 아직은 모르지만, 이미 알고 있었다면 나중에 바꿀지도 모릅니다. 그러므로, cellsPerSide라고 하는 다른 메서드로 숫자를 알려줄 책임을 부여하고 잠시동안 이대로 작성하도록 하겠습니다. initialize에 대한 메서드 내용을 accept 했을 때, "확인(confirm), 수정(correct) 또는 취소(cancel)" 를 물어보는 다이얼로그가 뜨게되는데 이것은 스퀵이 요청한 이름을 가진 메서드가 정의되기 이전에, cellsPerSide라는메시지를 보내기 때문입니다. 걱정하지 마십시오. 사실 이런 방법은 아직 정의하지 않은 다른 메서드를 가지고 작업을 진행하는 좋은 방법입니다. 왜일까요? 글쎄요, 우리가 이것이 필요하다고 깨달은 시점은 initialize 작성을 시작하기 전의 상황은 아니며, 지금 알았다고 해도 현재의 작업의 흐름을 방해하지 않으면서 의미있는 이름을 부여하고 옮길 수 있기 때문입니다.


네번째 줄은 이 메서드를 사용합니다. 스몰토크 self cellsPerSide는 cellsPerSide 메시지를 같은 오브젝트인 self에 보냅니다. 게임판의 각 모서리당 칸의 갯수 응답을 n에 할당합니다.


다음 세 줄은 새로운 SBECell 오브젝트를 만들고, 오브젝트의 너비와 높이를 적당한 임시 변수에 넣습니다.


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


마지막 줄은 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가 추가된것을 확인할 수 있다