# Tricky hash initialization

**URL:** <https://www.ruby-forum.com/t/tricky-hash-initialization/145913>\
**Category:** Ruby\
**Created:** [August 14, 2008, 11:18pm UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913 "2008-08-14T23:18:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 14, 2008, 11:18pm UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/1 "2008-08-14T23:18:28Z")

</div>

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

This is one level deep defaults to a fresh new hash.

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

This is two levels deep initialization to a fresh new hash.

How do I this for arbitrarily deep hashes?

h[“a”][“b”][“c”] = 3 #=\> {“c”=\>3}

I’m using this to build very clean implementations of state machine  
building algorithms.

Your help is very much appreciated.

-Ray

---

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 14, 2008, 11:23pm UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/2 "2008-08-14T23:23:05Z")

</div>

Ray Pereda wrote:

> How do I this for arbitrarily deep hashes?

Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}

HTH,  
Sebastian

---

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 15, 2008, 1:35am UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/3 "2008-08-15T01:35:42Z")

</div>

Sebastian H. wrote:

> Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}

Thanks for the attempt. Seems on the right track but not quite.

> > h = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}  
> > =\> {}
> 
> > h[“a”][“b”][“c”]  
> > =\> {}
> 
> > h  
> > =\> {“c”=\>{}}

After h[“a”][“b”][“c”]  
what needs to happen is h is equal to  
{“a”=\>{“b”=\>{“c”=\>{}}}}

Appreciating the Ruby Community’s Help,  
Ray

---

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 15, 2008, 1:54am UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/4 "2008-08-15T01:54:03Z")

</div>

On Aug 15, 2008, at 1:32, Ray Pereda wrote:

> > > h = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}

Don’t do that. The h inside the block is conflicting with the h  
outside. Make sure the variables don’t collide, and it works:

> > the\_hash = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}  
> > =\> {}
> 
> > the\_hash[:a][:b][:c]  
> > =\> {}
> 
> > the\_hash  
> > =\> {:a=\>{:b=\>{:c=\>{}}}}

---

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 15, 2008, 2:02am UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/5 "2008-08-15T02:02:50Z")

</div>

I should add: the same-variable-name version works in Ruby 1.9.

David

---

<div class="post-metadata">

**Author:** ![raypereda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ea666f/32.png) [@raypereda](https://www.ruby-forum.com/u/raypereda)\
**Post date:** [August 15, 2008, 1:55am UTC](https://www.ruby-forum.com/t/tricky-hash-initialization/145913/6 "2008-08-15T01:55:49Z")

</div>

Hi –

On Fri, 15 Aug 2008, Ray Pereda wrote:

> =\> {“c”=\>{}}
> 
> After h[“a”][“b”][“c”]  
> what needs to happen is h is equal to  
> {“a”=\>{“b”=\>{“c”=\>{}}}}

I think it’s a variable clobbering issue. Try this:

hash = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc) }

David
