修改默认哈希值

Ruby允许您为哈希定义默认值:

h=Hash.new(['alright']) h['meh'] # => ["alright"] 

显示散列时会显示值的赋值,但修改后的默认值不会。 哪里'bad'

 h['good']=['fine','dandy'] h['bad'].push('unhappy') h # => {"good"=>["fine", "dandy"]} 

如果我们明确要求, 'bad'出现。

 h['bad'] # => ["alright", "unhappy"] 

为什么在显示哈希时不会显示修改后的默认值?

哈希的默认值不像你期望的那样工作。 当你说h[k] ,过程如下:

  1. 如果我们有一个k键,则返回其值。
  2. 如果我们有Hash的默认值,则返回该默认值。
  3. 如果我们有一个用于提供默认值的块,请执行该块并返回其返回值。

注意,(2)和(3)没有说明将k插入哈希。 默认值实质上将h[k]变为:

 h.has_key?(k) ? h[k] : the_default_value 

因此,只需访问一个不存在的密钥并获取默认值就不会将缺少的密钥添加到哈希中。

此外,任何forms:

 Hash.new([ ... ]) # or Hash.new({ ... }) 

几乎总是一个错误,因为你将为所有默认值共享完全相同的默认数组或哈希值。 例如,如果您这样做:

 h = Hash.new(['a']) h[:k].push('b') 

然后h[:i]h[:j] ,…将全部返回['a', 'b'] ,这很少是你想要的。

我想你正在寻找默认值的块forms :

 h = Hash.new { |h, k| h[k] = [ 'alright' ] } 

这将做两件事:

  1. 访问不存在的密钥会将该密钥添加到哈希,并且它将提供所提供的数组作为其值。
  2. 所有默认值都是不同的对象,因此更改一个不会改变其余的对象。

发生了什么事情是你已经修改了哈希的默认值,通过push ‘unhappy’推到h['bad'] 。 你没有做的实际上是在哈希中添加了“坏”,这就是为什么当你检查h时它不会出现。

在您提供的所有代码之后,我尝试了这个:

 >> ph['bleh'] => ["allright", "unhappy"] 

这肯定告诉我默认值已经改变。 在回答你的问题’为什么修改后的默认值不会在显示哈希时显示?’时,你必须向它添加一个元素,而不是仅仅访问它:

 >> h['bleh'] # Doesn't add 'bleh' to the hash >> ph => {"good"=>["fine", "dandy"]} # See, no extra values >> h['bleh'] = h.default # Does add a new key with the default value >> ph => {"good"=>["fine", "dandy"], "bleh"=>["allright", "unhappy"]}