2014-09-16 2 views
0

기본값을 사용할 때마다 해시의 다른 인스턴스를 출력하기 위해 중첩 해시를 얻으려고합니다.해시 default-value가 동일한 인스턴스를 모두 만듭니다.

(인스턴스가 동일한 경우는 확인 내 자신의 인상에) 충돌 아래 코드 :

def reset_region_data 
    @region_data = Hash.new(Hash.new) 
    # @region_data = Hash.new{ Hash.new } # Same result as the line above 
    # @region_data = Hash.new { |hash,new_key| hash[new_key] = {} } # Same problem as the above lines. 
end 

def foo 
    reset_region_data 
    raise if @region_data[0].hash == @region_data[1 * 50 + 1].hash # <<<<< crashes 
end 

foo 

이 이상해. 해시가 동일한 인스턴스에 모두 기본값으로 설정되어 있습니까? 하지만 왜?

그러나이 코드는하지 않습니다

a = Hash.new(Hash.new()) 

a[10][10] = 1 
a[11][11] = 2 

raise if a[10][10].hash == a[11][11].hash 
p a[10][10] 

그리고이 코드는 충돌하지 않는 : 당신이 Hash.new을주는 경우에

a = Hash.new(Hash.new()) 

a[10] = 1 
a[11] = 2 

raise if a[10].hash == a[11].hash 
p a[10] 
+1

예외는 무엇입니까? 아마 당신은'Hash.new {Hash.new}'를 원할 것입니다; 그렇지 않으면 단일 해시가 만들어져 해시의 기본값으로 설정됩니다. 블록 폼이 호출되어 새로운 각 기본값에 대해 새 해시를 반환합니다. –

+0

내 자신의 인상은 예외입니다. 모든 인스턴스가 다르기를 원하기 때문입니다. 그러나 웬일인지, 그들은 그렇지 않다. 모든 @region_data [x]는 동일한 해시입니다 ... – Napoleon

+0

표시된대로 블록 양식을 사용하십시오. 당신은 하나의 해시를 만들고 모든 기본값에 대해 그 해시를 반환하고 있습니다. –

답변

2

는 (다른 Hash.new 등) 대상이 매우 객체는 기본입니다 값. 서로 다른 키에 걸쳐 이 공유됩니다.

default = [] 
hash = Hash.new(default) 
hash[:one] << 1 
# now default is [1] ! 

블록과 함께 Hash.new를 사용하면 키가 발견되지 않을 때마다 새로운 기능이 수행됩니다.

h = Hash.new { |hash,new_key| hash[new_key] = {} } 

처럼 그 예에 대한 좋은 설명이있다 Ruby hash default value behavior. 귀하의 질문은 일종의 중복입니다.

또한 설명에서 알 수 있듯이 object_id이 아닌 hash 값을 비교하려고합니다.

first_hash = {} 
second_hash = {} 

# .hash same, but different objects! 
puts "initial, hash:" 
puts first_hash.hash == second_hash.hash ? " - same" : " - differs" 
puts "initial, object_id" 
puts first_hash.object_id == second_hash.object_id ? " - same" : " - differs" 
puts 

# Change the world 
# .hash different, and still different objects. 
first_hash[:for] = "better" 
puts "better world now, hash:" 
puts first_hash.hash == second_hash.hash ? " - same" : " - differs" 
puts "better world now, object_id" 
puts first_hash.object_id == second_hash.object_id ? " - same" : " - differs" 
+0

그 중 하나가 작동하지 않습니다. 그러나 .hash를 .object_id로 바꾸는 것은 더 이상 내 "레이즈"를 발생시키지 않습니다. 어쩌면 나는 방금 object.hash를 잘못 사용했다 ... – Napoleon

+0

작동하지 않는다면 무엇을 의미합니까?! 'object_id'는 객체마다 고유합니다. '.hash'는 아닙니다 (동일한 텍스트를 담고있는 두 개의 문자열 변수는 같은 해시를 가지고 있지만 다른 object_id를 가지고 있습니다. 하나를 변경하면 해시는 변경하지만 object_id는 변경하지 않습니다). – Felix

+0

그 때 그것은 문제이었다. 나는 .object_id 대신 .hash 사이에 혼란스러워했다. object_id와 결합 된 대괄호가있는 코드 자체가 작동합니다. – Napoleon

관련 문제