# Double assignation in a hash

**URL:** <https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571>\
**Category:** Ruby\
**Created:** [June 5, 2008, 1:24am UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571 "2008-06-05T01:24:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 5, 2008, 1:24am UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/1 "2008-06-05T01:24:48Z")

</div>

hi !

I’m new to ruby, i’d like to know if it is possible to make the  
following kind of assignation in a hash, like i used to do in php :

a={}  
a[:b][:c]=“value”

the goal for me is to create a hash by iterating on keys, like

hash={}  
[a,b,c].each do |k1|  
[d,e,f].each do |k2|  
hash[k1][k2] = afunction(k1,k2)  
end  
end

this last code lead to a nil.[] error

Could you help me ? .

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 5, 2008, 1:43am UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/2 "2008-06-05T01:43:23Z")

</div>

On Jun 4, 2008, at 7:23 PM, nico Itkin wrote:

> hash={}  
> [a,b,c].each do |k1|  
> [d,e,f].each do |k2|  
> hash[k1][k2] = afunction(k1,k2)  
> end  
> end
> 
> this last code lead to a nil.[] error
> 
> Could you help me ? .

Your problem is that a[:b] is not a hash. You can get this effect by  
defining a default for the hash ‘a’ like so:

irb\> a = Hash.new {|h,k| h[k] = {} }  
=\> {}  
irb\> a[:b][:c] = ‘value’  
=\> “value”  
irb\> a  
=\> {:b=\>{:c=\>“value”}}

The block supplied to Hash.new is called with the hash and the key  
when the key doesn’t exist. So the effect is as if you had:

a = {}  
a[:b] = {}  
a[:b][:c] = ‘value’

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 5, 2008, 9:59am UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/3 "2008-06-05T09:59:02Z")

</div>

On Thu, Jun 5, 2008 at 1:23 AM, nico Itkin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> hi !
> 
> I’m new to ruby, i’d like to know if it is possible to make the  
> following kind of assignation in a hash, like i used to do in php :
> 
> a={}  
> a[:b][:c]=“value”

For arbitrary hash nesting, try this:

irb(main):023:0\> a = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}  
irb(main):024:0\> a[1][2][3][4] = “hello”  
irb(main):025:0\> a  
=\> {1=\>{2=\>{3=\>{4=\>“hello”}}}}  
irb(main):026:0\> a[1][2][3][4]  
=\> “hello”

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 5, 2008, 4:21am UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/4 "2008-06-05T04:21:34Z")

</div>

On Thu, Jun 05, 2008 at 08:23:53AM +0900, nico Itkin wrote:

> hash={}  
> [a,b,c].each do |k1|  
> [d,e,f].each do |k2|  
> hash[k1][k2] = afunction(k1,k2)  
> end  
> end
> 
> this last code lead to a nil.[] error
> 
> Could you help me ? .

You may find this of interest:

[http://redcorundum.blogspot.com/2007/05/just-nifty-meta-meta-tidbit.html](http://redcorundum.blogspot.com/2007/05/just-nifty-meta-meta-tidbit.html)

–Greg

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 6, 2008, 1:10pm UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/5 "2008-06-06T13:10:53Z")

</div>

JesÃºs Gabriel y GalÃ¡n wrote:

> For arbitrary hash nesting, try this:
> 
> irb(main):023:0\> a = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}  
> irb(main):024:0\> a[1][2][3][4] = “hello”  
> irb(main):025:0\> a  
> =\> {1=\>{2=\>{3=\>{4=\>“hello”}}}}  
> irb(main):026:0\> a[1][2][3][4]  
> =\> “hello”

Or this (longer but clearer IMO):

a = {}  
a[1] = {}  
a[1][2] = {}  
a[1][2][3] = {}  
a[1][2][3][4] = “hello”

print a[1][2][3][4] # “hello”

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 9, 2008, 2:19pm UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/6 "2008-06-09T14:19:08Z")

</div>

On Sun, Jun 8, 2008 at 10:25 PM, nico Itkin [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Thanks evebody for yours answers, helps a lot 🙂 !
> 
> Jesús : looks fantastic, but could you give me fex explanation how it  
> works?
> 
> > a = Hash.new {|h,k| h[k] = Hash.new(&h.default\_proc)}
> 
> is this a way to override the method new for the object a?
> 
> You’re doing so by passing the following block but then i’m lost, do you  
> have any links to share which detail that ?

Hash.new receives a block, which is executed whenever you try to access  
a non-existing key. In the block you can assign a value to the key in  
the hash.  
The value that we assign above is a hash. If we did this:

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

Then we would achieve a two-level hash, but the second level hash,  
wouldn’t be able to assign a next level hash to a non-existing key,  
because  
a block wasn’t provided.

Hash has a default\_proc variable that contains the block (in proc form)  
that was passed to the constructor, so if we assign this proc as the  
block  
for the constructor, we get a hash that can assign a hash to a  
non-existing key,  
in a recursive way, cause each hash will pass its default proc to the  
hash  
created in the constructor block.

So many words that I don’t know if I made myself clear…

Jesus.

---

<div class="post-metadata">

**Author:** ![itkin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/22d042/32.png) [@itkin](https://www.ruby-forum.com/u/itkin)\
**Post date:** [June 8, 2008, 10:26pm UTC](https://www.ruby-forum.com/t/double-assignation-in-a-hash/139571/7 "2008-06-08T22:26:27Z")

</div>

Thanks evebody for yours answers, helps a lot 🙂 !

JesÃºs : looks fantastic, but could you give me fex explanation how it  
works?

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

is this a way to override the method new for the object a?

You’re doing so by passing the following block but then i’m lost, do you  
have any links to share which detail that ?

Nico (so much to learn…)
