参见英文答案 >
Strange,unexpected behavior (disappearing/changing values) when using Hash default value,e.g. Hash.new([])5个
Ruby允许您为哈希定义默认值:
Ruby允许您为哈希定义默认值:
h=Hash.new(['alright']) h['meh'] # => ["alright"]
显示散列时会显示值的赋值,但修改后的默认值不会.哪里’糟糕’?
h['good']=['fine','dandy'] h['bad'].push('unhappy') h # => {"good"=>["fine","dandy"]}
如果我们明确要求,’坏’会出现.
h['bad'] # => ["alright","unhappy"]
解决方法
哈希的默认值不像你期望的那样工作.当你说h [k]时,过程如下:
>如果我们有一个k键,则返回其值.
>如果我们有Hash的默认值,则返回该默认值.
>如果我们有一个提供默认值的块,请执行该块并返回其返回值.
注意,(2)和(3)没有说明将k插入哈希.默认值实质上将h [k]变为:
h.has_key?(k) ? h[k] : the_default_value
因此,只需访问一个不存在的密钥并获取默认值就不会将缺少的密钥添加到哈希中.
此外,任何形式:
Hash.new([ ... ]) # or Hash.new({ ... })
几乎总是一个错误,因为你将为所有默认值共享完全相同的默认数组或哈希值.例如,如果您这样做:
h = Hash.new(['a']) h[:k].push('b')
然后h [:i],h [:j],…将全部返回[‘a’,’b’],这很少是你想要的.
我想你正在寻找block form of the default value:
h = Hash.new { |h,k| h[k] = [ 'alright' ] }
这将做两件事:
>访问不存在的密钥会将该密钥添加到哈希,并且它将提供的数组作为其值.>所有默认值都是不同的对象,因此更改其中一个不会改变其余对象.