Nested hash

S

Samuel Smith

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?
 
R

Robert Klemme

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?

No. Reason: you cannot override variable assignment - you can only
override assignment method like you did with []=.
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?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top