Hash of arrays - whats going on?

Discussion in 'Ruby' started by stephen O'D, Jul 19, 2007.

  1. stephen O'D

    stephen O'D Guest

    I want a hash, where the values of the keys are arrays, eg

    h = Hash.new
    h.default = []

    h['foo'] << 10
    h[foo'] << 20
    h['bar'] << 23
    h['bar'] << 33

    I thought this would give me

    { 'foo' => [20 30],
    'bar' => [23, 33] }

    but it doesn't - it seems to put the same array in the value of each
    key. Some googling revealed I need to create my hash like:

    h = Hash.new { |hash, key| hash[key] = [] }

    So my problem is solved, but why do you have to do it like this? At
    the risk of answering my own question, is it because the block is re-
    executed everytime you access a non existent key, creating a brand new
    array object, while the first way, it just initialises the value to
    the same array each time?

    Thanks,

    Stephen.
     
    stephen O'D, Jul 19, 2007
    #1
    1. Advertising

  2. stephen O'D

    Kyle Schmitt Guest

    default just lets you return a default value if the request key
    doesn't exist, it's not _supposed_ to change the state of the hash.

    What was happening is an array was presented to you when you called
    h['foo'], and you were putting a value in it, but the array was never
    saved to a variable, so it went away.

    With the original code try the following code, it may help you understand:
    h['foo'] << 10
    puts h.length
    h[foo'] << 20
    puts h.length
     
    Kyle Schmitt, Jul 19, 2007
    #2
    1. Advertising

  3. On Fri, Jul 20, 2007, stephen O'D wrote:
    > So my problem is solved, but why do you have to do it like this? At
    > the risk of answering my own question, is it because the block is re-
    > executed everytime you access a non existent key, creating a brand new
    > array object, while the first way, it just initialises the value to
    > the same array each time?


    The default value you provide is a reference... in this case, you say
    "use this array as the default value", not "use an empty array as a
    default value". To see what I mean, try this:

    empty_ary = []
    h = Hash.new
    h.default = empty_ary

    h['foo'] << 10
    puts empty_ary.size

    h[foo'] << 20
    puts empty_ary.size

    h['bar'] << 23
    puts empty_ary.size

    h['bar'] << 33
    puts empty_ary.size

    That should show you what's happening.

    Ben
     
    Ben Bleything, Jul 19, 2007
    #3
    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. sophie

    Whats going on - Char to Int Q:

    sophie, Jan 24, 2006, in forum: C Programming
    Replies:
    4
    Views:
    256
    Dave Thompson
    Feb 6, 2006
  2. Wardeaux

    Whats going on?

    Wardeaux, Feb 6, 2004, in forum: ASP .Net Web Controls
    Replies:
    6
    Views:
    147
    Jeffrey Tan[MSFT]
    Feb 12, 2004
  3. jason
    Replies:
    2
    Views:
    129
    jason
    Sep 16, 2003
  4. rp
    Replies:
    1
    Views:
    556
    red floyd
    Nov 10, 2011
  5. Erik Boling

    Whats going on!?!?

    Erik Boling, Oct 2, 2007, in forum: Ruby
    Replies:
    10
    Views:
    197
    Erik Boling
    Oct 5, 2007
Loading...

Share This Page