SqueakByExample:9.6

From 흡혈양파의 번역工房
Revision as of 05:10, 30 August 2012 by Onionmixer (talk | contribs)
Jump to navigation Jump to search

컬렉션 사용을 위한 몇 가지 힌트

add:를 사용할 때 저지르는 일반적인 실수: 다음 에러는 가장 빈번한 스몰토크 실수들 중의 하나 입니다.

collection := OrderedCollection new add: 1; add: 2.
collection        2


여기에 나온 변수 컬렉션(collection)은 새롭게 만들어진 컬렉션(collection)을 보유하지 않고 오히려 추가된 마지막 숫자를 보유합니다. 그 이유는 메서드 add:가 추가된 구성요소를 리턴하고 수신자(the receiver)를 리턴하지 않기 때문입니다.

다음 코드는 기대한 결과를 도출합니다:

collection := OrderedCollection new.
collection add: 1; add: 2.
collection        an OrderedCollection(1 2)


여러분은 또한 메시지들의 캐스케이드(cascade)의 수신자를 리턴하기 위해 메시지 yourself를 사용할 수 있습니다.

collection := OrderedCollection new add: 1; add: 2; yourself         an OrderedCollection(1 2)


여러분이 반복적용(iterating)을 수행하는 컬렉션에 있는 구성요소를 제거합니다. 여러분이 할 수 있는 다른 실수는 여러분이 현재 반복적용을 수행하는 위치인 컬렉션에 있는 구성요소를 제거하는 것입니다. remove:

range := (2 to: 20) asOrderedCollection.
range do: [:aNumber | aNumber isPrime ifFalse: [ range remove: aNumber ] ].
range        an OrderedCollection(2 3 5 7 9 11 13 15 17 19)


9와 15가 필터링 되었어야만 했었기 때문에, 결과는 명백하게 정확한 것은 아닙니다.

솔루션은 철저한 검사를 하기 전에 컬렉션(collection)을 복사하는 것입니다.

range := (2 to: 20) asOrderedCollection.
range copy do: [:aNumber | aNumber isPrime ifFalse: [ range remove: aNumber ] ].
range        an OrderedCollection(2 3 5 7 11 13 17 19)


= 와 hash를 재정의 합니다. 알아내기가 어려운 에러는 여러분이 =를 재정의 할 때이며, hash를 재정의 할 때가 아닙니다. 이 에러의 증상들은 세트(sets)에 집어넣을 구성요소들을 손실하게 되거나 다른 이상한 동작이 발생하는 것입니다. Kent Beck에 의해 제안된 솔루션은 hash를 재정의 하기 위해 xor:을 사용하는 것입니다. 만약 우리가 제목과 저자가 동일할 경우, 두 개의 책이 동일한 것으로 간주될 2 권의 책을 원한다고 가정해 본다면, 우리는 다음과 같이 =를 재정의할 뿐만 아니라 hash도 재정의 해야 할 것입니다.


메서드 9.1 =과 hash를 재정의 하기

Book»= aBook
  self class = aBook class ifFalse: [ false].
   title = aBook title and: [ authors = aBook authors]

Book»hash
   title hash xor: authors hash


만약 여러분이 예를 들어 Set의 구성요소 또는 Dictionary에 대한 Key로서 그 자체의 hash 값을 변경할 수 있는 오브젝트와 같이, 수정 가능한 오브젝트(mutable object)를 사용하신다면, 또 다른 끔찍한 문제가 발생합니다. 여러분이 디버깅을 사랑하지 않는다면, 수정 가능한 오브젝트를 사용하지 말아 주세요!


Notes