Nested hash

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?

···

--
Posted via http://www.ruby-forum.com/.

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

···

On 04/05/2010 04:34 PM, Samuel Smith wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/