Linked Questions

Popular Questions

Nested Hash Via Recursion in Ruby

Asked by At

I've been trying to make a nested default hash programmatically in Ruby, basically a short-hand for Ruby's :

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

I'd like to extend this to work to as many levels as needed. I made the following function:

def nested_hash(level, default={})
   return default if level == 0
   return Hash.new{ |h,k| h[k] = nested_hash(level - 1, default) }
end

It looks like it's working correctly but I run into the following issue when creating multiple keys

h = nested_hash(1)
h[0][1] = [1, 2, 3] # h is {0=>{1=>[1, 2, 3]}}
h[2] # should give a new Hash, but returns {1=>[1, 2, 3]}
h # {0=>{1=>[1, 2, 3]}, 2=>{1=>[1, 2, 3]}} 

Why is the default value changing for the function and becoming the previously set value?

EDIT

I've found a solution that works:

def nested_hash(level, default={})
    return Hash.new{ |h,k| h[k] = default } if level <= 1
    Hash.new{ |h,k| h[k] = nested_hash(level - 1, default) }
end

Never mind, this doesn't work either in a similar way:

h = nested_hash(1)
h[0][1] = [1, 2, 3]
h[2][0] # nil
h # {0=>{1=>[1, 2, 3]}, 2=>{1=>[1, 2, 3]}}

I'm still confused as to why the original default was shared amongst the keys.

Related Questions