SqueakByExample:9.6: Difference between revisions

From 흡혈양파의 번역工房
Jump to navigation Jump to search
mNo edit summary
(번역수정)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
==컬렉션 사용을 위한 몇 가지 힌트==
==컬렉션 사용에 대한 몇 가지 힌트==
 
'''add: 메서드를 사용할 때 발생되는 일반적인 실수:''' 다음의 에러는 가장 많이 발생되는 스몰토크 코딩에서의 실수 중 하나 입니다.


'''add:를 사용할 때 저지르는 일반적인 실수:''' 다음 에러는 가장 빈번한 스몰토크 실수들 중의 하나 입니다.
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
collection := OrderedCollection new add: 1; add: 2.
collection := OrderedCollection new add: 1; add: 2.
Line 8: Line 9:




여기에 나온 변수 컬렉션(collection)은 새롭게 만들어진 컬렉션(collection)을 보유하지 않고 오히려 추가된 마지막 숫자를 보유합니다. 그 이유는 메서드 add:추가된 구성요소를 리턴하고 수신자(the receiver)를 리턴하지 않기 때문입니다.
여기서 보게되는 변수 collection 은 새롭게 만들어진 컬렉션이 아니라, 마지막에 추가된 숫자를 보관합니다. 왜냐하면 메서드 add: 추가된 요소를 반환하되, 수신자는 반환하지 않기 때문입니다.
 
다음 코드에서 예상대로의 결과를 얻을 수 있습니다:


다음 코드는 기대한 결과를 도출합니다:
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
collection := OrderedCollection new.
collection := OrderedCollection new.
Line 18: Line 20:




여러분은 또한 메시지들의 캐스케이드(cascade)의 수신자를 리턴하기 위해 메시지 yourself를 사용할 수 있습니다.   
그외에 yourself 메시지를 사용할 수 있는데, 이 메시지는 cascade 된 메시지의 수신자를 반환합니다.   
 
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
collection := OrderedCollection new add: 1; add: 2; yourself    ⇒    an OrderedCollection(1 2)
collection := OrderedCollection new add: 1; add: 2; yourself    ⇒    an OrderedCollection(1 2)
Line 24: Line 27:




'''여러분이 반복적용(iterating)을 수행하는 컬렉션에 있는 구성요소를 제거합니다.''' 여러분이 할 수 있는 다른 실수는 여러분이 현재 반복적용을 수행하는 위치인 컬렉션에 있는 구성요소를 제거하는 것입니다. remove:
'''반복을 수행하고 있는 콜렉션으로부터 요소를 삭제.''' 자주 일어날 수 있는 다른 실수는, 현재 반복작업을 수행하는 컬렉션으로부터 요소를 제거하는 것입니다. remove: 를 이용하는 경우에 말이죠.
 
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
range := (2 to: 20) asOrderedCollection.
range := (2 to: 20) asOrderedCollection.
Line 32: Line 36:




9와 15가 필터링 되었어야만 했었기 때문에, 결과는 명백하게 정확한 것은 아닙니다.
9 와 15 가 걸러져야 했기 때문에, 결과는 잘못된 결과입니다.
 
해결 방법은, 검사를 하기 전에 컬렉션을 복사해 두는 것입니다.  


솔루션은 철저한 검사를 하기 전에 컬렉션(collection)을 복사하는 것입니다.
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
range := (2 to: 20) asOrderedCollection.
range := (2 to: 20) asOrderedCollection.
Line 42: Line 47:




'''= 와 hash를 재정의 합니다.''' 알아내기가 어려운 에러는 여러분이 =를 재정의 할 때이며, hash를 재정의 할 때가 아닙니다. 이 에러의 증상들은 세트(sets)집어넣을 구성요소들을 손실하게 되거나 다른 이상한 동작이 발생하는 것입니다. Kent Beck에 의해 제안된 솔루션은 hash를 재정의 하기 위해 xor:을 사용하는 것입니다. 만약 우리가 제목과 저자가 동일할 경우, 두 개의 책이 동일한 것으로 간주될 2 권의 책을 원한다고 가정해 본다면, 우리는 다음과 같이 =를 재정의할 뿐만 아니라 hash도 재정의 해야 할 것입니다.
'''= 와 hash 는 한번에 양쪽 모두 재정의 되어야 한다.''' 에러중 발견하기 어려운 경우는, 사용자가 = 을 재정의하면서 hash 는 재정의하지 않는 경우입니다. 이런경우 Set 분명히 넣은 요소가 어느새 없어진다는 현상등이 나타납니다. Kent Beck 이 제안한 해결책은 xor: 을 이용해서 bash를 재정의 하는 것입니다. 예를 들어, 만약 제목과 저자가 같은경우, 두 개의 책을 동일한 것으로 판단하고 싶을때, 다음과 같이 = 를 재정의할 뿐만 아니라 hash도 재정의 해야 할 것입니다.




메서드 9.1 =과 hash를 재정의 하기
메서드 9.1 = 과 hash 재정의 하기
 
<syntaxhighlight lang="smalltalk">
<syntaxhighlight lang="smalltalk">
Book»= aBook
Book»= aBook
Line 56: Line 62:




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





Latest revision as of 16:38, 13 September 2013

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

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