Project

General

Profile

Actions

Bug #12269

closed

Nesting Two-levels of Hash with Hash as default value makes top level Hash not list keys/values and causes reference issue with nested values.

Added by spacemunkay (Jason Denney) over 8 years ago. Updated over 8 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:74883]

Description

Nesting Hashes that have Hashes as default values cause the 1st (top) level hash to not list keys or values. Also, it is possible to overwrite the values of keys in the 2nd level hash via new assignments to entirely different keys on the 2nd level hash.

See the following IRB session for behavior:

2.3.0 :001 > h = Hash.new( Hash.new({}) )
 => {}
2.3.0 :002 > h['a']['b']['c'] = true
 => true
2.3.0 :003 > h.inspect
 => "{}"
2.3.0 :004 > h['a']['b']['c']
 => true
2.3.0 :005 > h['a']['Z']['c'] = false
 => false
2.3.0 :006 > h['a']['b']['c']
 => false

The only vaguely related bug report I could find was: [[https://bugs.ruby-lang.org/issues/12098]]

Updated by nobu (Nobuyoshi Nakada) over 8 years ago

  • Status changed from Open to Rejected

Try h.default.default.

Updated by shyouhei (Shyouhei Urabe) over 8 years ago

Re: "it is possible to overwrite the values of keys in the 2nd level hash via new assignments to entirely different keys on the 2nd level hash"

It is per spec. The hash default value is shared among keys. This is not only for nested hashes, but also other kind of objects such as strings.

irb(main):001:0> h=Hash.new('foo')
=> {}
irb(main):002:0> h['bar']
=> "foo"
irb(main):003:0> h['baz'].clear
=> ""
irb(main):004:0> h['bar']
=> ""
irb(main):005:0>

If you want you can avoid this by passing block to Hash.new, like Hash.new {|x, y| ... } This way hash defaults are generated every time using the block.

Actions

Also available in: Atom PDF

Like0
Like0Like0