From: Austin Ziegler Date: 2015-01-07T20:37:05-05:00 Subject: [ruby-core:67416] Re: [ruby-trunk - Bug #10713] Assigning default value for a Hash as an empty Array creating unpredictable results --089e0129503e15cd93050c1a1599 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable It's quite expected because the default array is created exactly once: letters =3D Hash.new([]) letters.default.object_id # =3D> 70310393550400 letters[:a].object_id # =3D> 70310393550400 letters[:b].object_id # =3D> 70310393550400 The pattern that Arvinder *wants* is: letters =3D Hash.new { |h, k| h[k] =3D [] } letters.default # =3D> nil letters.default_proc # =3D> # letters[:a].object_id # =3D> 70310393174180 letters[:b].object_id # =3D> 70310393171680 It's possible to make the correct pattern do the "wrong thing": array =3D [] array.object_id # =3D> 70310393550400 letters =3D Hash.new { |h, k| h[k] =3D array } letters.default # =3D> nil letters.default_proc # =3D> # letters[:a].object_id # =3D> 70310393550400 letters[:b].object_id # =3D> 70310393550400 -a On Wed, Jan 7, 2015 at 8:16 PM, wrote: > Issue #10713 has been updated by Martin D=FCrst. > > > 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 =3D Hash.new([]) > =3D> {} > irb(main):002:0> letters[:a] << 1 > =3D> [1] > irb(main):003:0> letters[:a] << 2 > =3D> [1, 2] > irb(main):004:0> letters[:a] > =3D> [1, 2] > irb(main):005:0> letters > =3D> {} > ~~~ > > whereas the following code explicitly defining hash keys works. > > ~~~ > irb(main):001:0> letters =3D {a: [], b: []} > =3D> {:a=3D>[], :b=3D>[]} > irb(main):002:0> letters[:a] << 1 > =3D> [1] > irb(main):003:0> letters[:a] << 2 > =3D> [1, 2] > irb(main):004:0> letters[:a] > =3D> [1, 2] > irb(main):005:0> letters > =3D> {:a=3D>[1, 2], :b=3D>[]} > ~~~ > > 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/ > --=20 Austin Ziegler * halostatue@gmail.com * austin@halostatue.ca http://www.halostatue.ca/ * http://twitter.com/halostatue --089e0129503e15cd93050c1a1599 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
It’s quite expected because the default array is cre= ated exactly once:

letters =3D Hash.new([])
letters.d= efault.object_id # =3D> 70310393550400
letters[:a].object_id # = =3D> 70310393550400
letters[:b].object_id # =3D> 7031039355= 0400

The pattern that Arvinder *wants* is= :

letters =3D Hash.new { |h, k| h[k] =3D [] }
letters.default # =3D> nil
letters.default_proc # =3D>= ; #<Proc:0x007fe4d4099988@(irb):7>
letters[:a].object_id # = =3D> 70310393174180
letters[:b].object_id # =3D> 70310393171680

It’s possib= le to make the correct pattern do the “wrong thing”:
=
array =3D []
array.object_id # =3D> 70310393550= 400
letters =3D Hash.new { |h, k| h[k] =3D array }
letters.default # =3D> nil
letters.default_proc # =3D> #&l= t;Proc:0x007fe4d4099988@(irb):7>
letters[:a].object= _id # =3D> 70310393550400
letters[:b].object_id # =3D> 7031= 0393550400

-a

On Wed, Jan 7, = 2015 at 8:16 PM, <duerst@it.aoyama.ac.jp> wrote:
Issue #10713 has been updated by Martin D=FCrs= t.


Hiroshi SHIBATA wrote:
> It's expected behavior

Hiroshi, can you tell us why it's expected behavior? It looks quite sur= prising.

----------------------------------------
Bug #10713: Assigning default value for a Hash as an empty Array creating u= npredictable 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 i= s an empty Array.

E.g. the following returns an empty Hash...

~~~
irb(main):001:0> letters =3D Hash.new([])
=3D> {}
irb(main):002:0> letters[:a] << 1
=3D> [1]
irb(main):003:0> letters[:a] << 2
=3D> [1, 2]
irb(main):004:0> letters[:a]
=3D> [1, 2]
irb(main):005:0> letters
=3D> {}
~~~

whereas the following code explicitly defining hash keys works.

~~~
irb(main):001:0> letters =3D {a: [], b: []}
=3D> {:a=3D>[], :b=3D>[]}
irb(main):002:0> letters[:a] << 1
=3D> [1]
irb(main):003:0> letters[:a] << 2
=3D> [1, 2]
irb(main):004:0> letters[:a]
=3D> [1, 2]
irb(main):005:0> letters
=3D> {:a=3D>[1, 2], :b=3D>[]}
~~~

Is this an unpredictable(bug) or an expected behavior(feature). I tend to l= ean towards the former, but I might be wrong.



--
https://bugs.ruby= -lang.org/



--
=
--089e0129503e15cd93050c1a1599--