Hash hidden in hash with default object

Discussion in 'Ruby' started by Marcel Molina Jr., Jun 25, 2005.

  1. I observed this odd behavior when setting a hash to have as its default
    value another hash which itself has a default value set:

    >> hash_in_hash = Hash.new(Hash.new([]))

    => {}
    >> hash_in_hash[:a][:b] << :incognito

    => [:incognito]
    >> hash_in_hash

    => {}
    >> hash_in_hash[:a]

    => {}
    >> hash_in_hash.keys

    => []
    >> hash_in_hash[:a][:b]

    => [:incognito]
    >> hash_in_hash[:a].keys

    => []

    ?

    marcel
    --
    Marcel Molina Jr. <>
    Marcel Molina Jr., Jun 25, 2005
    #1
    1. Advertising

  2. On Sun, Jun 26, 2005 at 12:53:59AM +0900, Marcel Molina Jr. wrote:
    > I observed this odd behavior when setting a hash to have as its default
    > value another hash which itself has a default value set:
    >
    > >> hash_in_hash = Hash.new(Hash.new([]))

    > => {}
    > >> hash_in_hash[:a][:b] << :incognito

    > => [:incognito]
    > >> hash_in_hash

    > => {}
    > >> hash_in_hash[:a]

    > => {}
    > >> hash_in_hash.keys

    > => []
    > >> hash_in_hash[:a][:b]

    > => [:incognito]
    > >> hash_in_hash[:a].keys

    > => []


    Responding to myself...

    To achieve the desired result in this case I should be using the block form.

    Thanks for taking a look. I'll figure this out...

    marcel
    --
    Marcel Molina Jr. <>
    Marcel Molina Jr., Jun 25, 2005
    #2
    1. Advertising

  3. On 6/25/05, Marcel Molina Jr. <> wrote:
    > I observed this odd behavior when setting a hash to have as its default
    > value another hash which itself has a default value set:


    > >> hash_in_hash =3D Hash.new(Hash.new([]))

    > =3D> {}
    > >> hash_in_hash[:a][:b] << :incognito

    > =3D> [:incognito]
    > >> hash_in_hash

    > =3D> {}
    > >> hash_in_hash[:a]

    > =3D> {}
    > >> hash_in_hash.keys

    > =3D> []
    > >> hash_in_hash[:a][:b]

    > =3D> [:incognito]
    > >> hash_in_hash[:a].keys

    > =3D> []


    That's now how you want to do this in any case, because that doesn't
    actually *set* the key. Even if it did, it's still probably not what
    you want, because all of the secondary hashes will be referencing
    the same array as their default value, e.g.:

    hash_in_hash[:a][:c] << :cognito
    =3D> [:incognito, :cognito]

    Instead, do:

    hash_in_hash =3D Hash.new { |h, k|
    h[k] =3D Hash.new { |h1, k1|
    h1[k1] =3D []
    }
    }

    -austin
    --=20
    Austin Ziegler *
    * Alternate:
    Austin Ziegler, Jun 25, 2005
    #3
  4. On Sun, Jun 26, 2005 at 01:28:08AM +0900, Austin Ziegler wrote:
    > On 6/25/05, Marcel Molina Jr. <> wrote:
    > > I observed this odd behavior when setting a hash to have as its default
    > > value another hash which itself has a default value set:

    >
    > > >> hash_in_hash = Hash.new(Hash.new([]))

    > > => {}
    > > >> hash_in_hash[:a][:b] << :incognito

    > > => [:incognito]
    > > >> hash_in_hash

    > > => {}
    > > >> hash_in_hash[:a]

    > > => {}
    > > >> hash_in_hash.keys

    > > => []
    > > >> hash_in_hash[:a][:b]

    > > => [:incognito]
    > > >> hash_in_hash[:a].keys

    > > => []

    >
    > That's now how you want to do this in any case, because that doesn't
    > actually *set* the key. Even if it did, it's still probably not what
    > you want, because all of the secondary hashes will be referencing
    > the same array as their default value, e.g.:
    >
    > hash_in_hash[:a][:c] << :cognito
    > => [:incognito, :cognito]
    >
    > Instead, do:
    >
    > hash_in_hash = Hash.new { |h, k|
    > h[k] = Hash.new { |h1, k1|
    > h1[k1] = []
    > }
    > }


    Thanks for the reply. That's exactly what I came up with except I foolishly
    did

    Hash.new {|h,k| h[k] = Hash.new {|h1,k1| h1[k1] ||= [] }}

    (difference is ||= [] vs = []) which causes SystemStackError.

    Thanks again.

    marcel
    --
    Marcel Molina Jr. <>
    Marcel Molina Jr., Jun 25, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rick
    Replies:
    3
    Views:
    8,074
    Alexey Smirnov
    Apr 13, 2010
  2. rp
    Replies:
    1
    Views:
    478
    red floyd
    Nov 10, 2011
  3. Pokkai Dokkai
    Replies:
    8
    Views:
    119
    Phrogz
    Nov 18, 2007
  4. Srijayanth Sridhar
    Replies:
    19
    Views:
    581
    David A. Black
    Jul 2, 2008
  5. SolarCanine
    Replies:
    2
    Views:
    242
    SolarCanine
    Sep 20, 2005
Loading...

Share This Page