2010-04-22 84 views
2

今天我试了下面的代码片段,我不明白为什么我会在它们之间得到不同的结果。据我所知他们是一样的。未使用哈希默认值

其中一个使用默认值off Hash,另一个片段在密钥被访问之前为该密钥创建一个空数组。

任何了解正在发生的事情的人? :)

# Hash default if the key doesn't have a value set is an empty Array 
a = Hash.new([]) 
a[:key] << 2 # => [2] 
p a # => {} nil 
p a[:key] # => [2] 
p a.keys # => [] 
p a.values # => [] 

# Explicitly add an array for all nodes before creating 
b = Hash.new 
b[:key] ||= [] 
b[:key] << 2 # => [2] 
p b # => {:key=>[2]} 
p b.keys # => [:key] 

的Ruby版本1.8.7

+2

我有同样的问题,前一段时间: http://stackoverflow.com/questions/2552579/ruby-method-array-not-updating-the-array -in-hash – 2010-04-22 15:28:23

+0

我不认为它们是相同的。如果我尝试使用块,就像你一样,我看不到使用'p a [:key]'输入的值。但是,默认不是块,我确实得到了值,但除非我调用特定的键,否则它不会显示。用'a.keys'或'a.value',我得到一个空的'Array'。 似乎是一种将密钥添加到“哈希”中的方式,无论出于何种原因,这都是好的。 – gaqzi 2010-04-22 15:59:49

+0

对不起,不完全一样。你已经改变了默认值(尝试在第一个例子中打印'a [:foo]',你会看到)。我总是从一个空阵列开始。顺便说一句,我也问过这一个,似乎更加类似:http://stackoverflow.com/questions/1822021/why-does-hash-new-hide-hash-members – 2010-04-22 16:15:45

回答

4

当你做a[:key] << 2,你说溜空数组默认值并加入2到它(修改实际的数组,而不是引用)而不让哈希对象a知道你改变了任何东西。你修改了a使用作为默认的对象,所以你会看到这个问题,以及:

p a[:wat] #=> [2] 
p a[:anything] #=> [2] 

在第二个例子,你犯了一个新的数组,并使用b[:key]=告诉b,它有下一个值那把钥匙。

c = Hash.new([]) 
c[:key] += [2] 

这将访问c[:key]并作出新的阵列+并重新分配它:

,如果你想两全其美的尝试。

5

也许这将帮助:

a = Hash.new { |hash, key| hash[key] = [] } 
a[:key] << 2 # => [2] 
a[:key]  # => [2] 
p a   # => {:key=>[2]}