# Nested hash

**URL:** <https://www.ruby-forum.com/t/nested-hash/186352>\
**Category:** Ruby\
**Created:** [April 5, 2010, 4:34pm UTC](https://www.ruby-forum.com/t/nested-hash/186352 "2010-04-05T16:34:46Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![shortnose](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@shortnose](https://www.ruby-forum.com/u/shortnose)\
**Post date:** [April 5, 2010, 4:34pm UTC](https://www.ruby-forum.com/t/nested-hash/186352/1 "2010-04-05T16:34:46Z")

</div>

Hello All.

Sample code:

class NestedHash \< Hash  
attr\_accessor :val  
alias :to\_str :to\_s  
@val=0  
def initialize  
blk = lambda {|h,k| h[k] = NestedHash.new(&blk)}  
super(&blk)  
end  
def []= (key,value)  
if value.is\_a?(NestedHash)  
super(key,value)  
else  
self[key].val=value;  
end  
end  
end

test=NestedHash.new();  
test[‘1’]=‘11’  
test[‘1’][‘2’]=‘12’  
test[‘1’][‘3’]=‘13’  
test[‘2’][‘4’]=‘24’

s=test[‘1’].val #s=‘11’

Work as expected. In C++ by using typecast overloading it is possible to  
implement class that will work that way:  
s=test[‘1’]# s=‘11’

Is it possible to implement same functionality in Ruby?

I’ve tried:

alias :to\_s :to\_str  
def to\_str  
@val  
end

But first of all result values are wrong and i can’t understand why.  
Secondly it works only in constructions like that:  
s=" "+test[‘1’] # ie i must tell Ruby that i need string result  
but not in  
s=test[‘1’] # if it were possible to tell Ruby that it use string result  
by default

Any other suggestions?

---

<div class="post-metadata">

**Author:** ![shortnose](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@shortnose](https://www.ruby-forum.com/u/shortnose)\
**Post date:** [April 5, 2010, 7:16pm UTC](https://www.ruby-forum.com/t/nested-hash/186352/2 "2010-04-05T19:16:08Z")

</div>

On 04/05/2010 04:34 PM, Samuel S. wrote:

> ```
> super(&blk)
> 
> ```
> 
> test=NestedHash.new();
> 
> Is it possible to implement same functionality in Ruby?

No. Reason: you cannot override variable assignment - you can only  
override assignment method like you did with []=.

> but not in  
> s=test[‘1’] # if it were possible to tell Ruby that it use string result  
> by default
> 
> Any other suggestions?

I would disallow mixing nesting and values. Compare it to a filesystem:  
something is either a directory or not. If it is a directory you can  
put arbitrary things in it but there is no special file for a certain  
directory (keeping resource forks and other file system specialties  
aside for a moment). This is conceptually simpler - and it also makes  
the implementation easier because you do not need an extra class for  
this:

robert@fussel:~$ ruby19 -e ‘ha=Hash.new {|h,k|  
h[k]=Hash.new(&h.default\_proc)};ha[1][2][3]=4;p ha’  
{1=\>{2=\>{3=\>4}}}  
robert@fussel:~$

Depending on the context a totally different approach might be even more  
reasonable: if the types you want to nest are known you could create a  
set of Struct classes that exactly represent what you want to model. Of  
course this approach does not work with a generic mechanism (e.g.  
storing a different representation of any XML document).

Kind regards

robert
