From: halostatue@... Date: 2015-01-08T01:38:21+00:00 Subject: [ruby-core:67417] [ruby-trunk - Bug #10713] Assigning default value for a Hash as an empty Array creating unpredictable results Issue #10713 has been updated by Austin Ziegler. It's quite expected because the default array is created exactly once: letters = Hash.new([]) letters.default.object_id # => 70310393550400 letters[:a].object_id # => 70310393550400 letters[:b].object_id # => 70310393550400 The pattern that Arvinder *wants* is: letters = Hash.new { |h, k| h[k] = [] } letters.default # => nil letters.default_proc # => # letters[:a].object_id # => 70310393174180 letters[:b].object_id # => 70310393171680 It's possible to make the correct pattern do the "wrong thing": array = [] array.object_id # => 70310393550400 letters = Hash.new { |h, k| h[k] = array } letters.default # => nil letters.default_proc # => # letters[:a].object_id # => 70310393550400 letters[:b].object_id # => 70310393550400 -a On Wed, Jan 7, 2015 at 8:16 PM, wrote: > Issue #10713 has been updated by Martin D��rst. > > > Hiroshi SHIBATA wrote: > > It's expected behavior > > Hiroshi, can you tell us why it's expected behavior? It looks quite > surprising. > > ---------------------------------------- > Bug #10713: Assigning default value for a Hash as an empty Array creating > unpredictable results > https://bugs.ruby-lang.org/issues/10713#change-50846 > > * Author: Arvinder Singh > * Status: Rejected > * Priority: Normal > * Assignee: > * Category: core > * Target version: current: 2.2.0 > * ruby -v: ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14] > * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN > ---------------------------------------- > Creating a Hash with a default value works fine, unless the default value > is an empty Array. > > E.g. the following returns an empty Hash... > > ~~~ > irb(main):001:0> letters = Hash.new([]) > => {} > irb(main):002:0> letters[:a] << 1 > => [1] > irb(main):003:0> letters[:a] << 2 > => [1, 2] > irb(main):004:0> letters[:a] > => [1, 2] > irb(main):005:0> letters > => {} > ~~~ > > whereas the following code explicitly defining hash keys works. > > ~~~ > irb(main):001:0> letters = {a: [], b: []} > => {:a=>[], :b=>[]} > irb(main):002:0> letters[:a] << 1 > => [1] > irb(main):003:0> letters[:a] << 2 > => [1, 2] > irb(main):004:0> letters[:a] > => [1, 2] > irb(main):005:0> letters > => {:a=>[1, 2], :b=>[]} > ~~~ > > Is this an unpredictable(bug) or an expected behavior(feature). I tend to > lean towards the former, but I might be wrong. > > > > -- > https://bugs.ruby-lang.org/ > -- Austin Ziegler * halostatue@gmail.com * austin@halostatue.ca http://www.halostatue.ca/ * http://twitter.com/halostatue ---------------------------------------- Bug #10713: Assigning default value for a Hash as an empty Array creating unpredictable results https://bugs.ruby-lang.org/issues/10713#change-50848 * Author: Arvinder Singh * Status: Rejected * Priority: Normal * Assignee: * Category: core * Target version: current: 2.2.0 * ruby -v: ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14] * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- Creating a Hash with a default value works fine, unless the default value is an empty Array. E.g. the following returns an empty Hash... ~~~ irb(main):001:0> letters = Hash.new([]) => {} irb(main):002:0> letters[:a] << 1 => [1] irb(main):003:0> letters[:a] << 2 => [1, 2] irb(main):004:0> letters[:a] => [1, 2] irb(main):005:0> letters => {} ~~~ whereas the following code explicitly defining hash keys works. ~~~ irb(main):001:0> letters = {a: [], b: []} => {:a=>[], :b=>[]} irb(main):002:0> letters[:a] << 1 => [1] irb(main):003:0> letters[:a] << 2 => [1, 2] irb(main):004:0> letters[:a] => [1, 2] irb(main):005:0> letters => {:a=>[1, 2], :b=>[]} ~~~ Is this an unpredictable(bug) or an expected behavior(feature). I tend to lean towards the former, but I might be wrong. -- https://bugs.ruby-lang.org/