SqueakByExample:9.6

From 흡혈양파의 번역工房
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

컬렉션 사용에 대한 몇 가지 힌트

add: 메서드를 사용할 때 발생되는 일반적인 실수: 다음의 에러는 가장 많이 발생되는 스몰토크 코딩에서의 실수 중 하나 입니다.

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


여기서 보게되는 변수 collection 은 새롭게 만들어진 컬렉션이 아니라, 마지막에 추가된 숫자를 보관합니다. 왜냐하면 메서드 add: 는 추가된 요소를 반환하되, 수신자는 반환하지 않기 때문입니다.

다음 코드에서 예상대로의 결과를 얻을 수 있습니다:

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


그외에 yourself 메시지를 사용할 수 있는데, 이 메시지는 cascade 된 메시지의 수신자를 반환합니다.

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


반복을 수행하고 있는 콜렉션으로부터 요소를 삭제. 자주 일어날 수 있는 또 다른 실수는, 현재 반복작업을 수행하는 컬렉션으로부터 요소를 제거하는 것입니다. 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 가 걸러져야 했기 때문에, 이 결과는 잘못된 결과입니다.

해결 방법은, 검사를 하기 전에 컬렉션을 복사해 두는 것입니다.

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 는 재정의하지 않는 경우입니다. 이런경우 Set 에 분명히 넣은 요소가 어느새 없어진다는 현상등이 나타납니다. Kent Beck 이 제안한 해결책은 xor: 을 이용해서 bash를 재정의 하는 것입니다. 예를 들어, 만약 제목과 저자가 같은경우, 두 개의 책을 동일한 것으로 판단하고 싶을때, 다음과 같이 = 를 재정의할 뿐만 아니라 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 값의 변경이 가능한 객체처럼-수정가능한 객체를 사용하는 경우에는, 또 다른 끔찍한 문제가 발생합니다. 당신이 디버깅을 정말로 좋아하는게 아니라면, 이런 경우에는 수정가능한 객체를 사용하지 말아주세요!


Notes