# Something wrong with my hash of hash - RUBY

This is a discussion on Something wrong with my hash of hash - RUBY ; I try to get a hash of hash to make some sort of counter (I have a set of random pair and want to count the number of times they appear). I use this code but even if I can ...

1. ## Something wrong with my hash of hash

I try to get a hash of hash to make some sort of counter (I have a set
of random pair and want to count the number of times they appear). I use
this code but even if I can access data, my hash seems empty (so each
and the others don't work):

h = Hash.new(Hash.new(0))
h["a"]["b"] += 1
h["a"]["b"] += 1
h["a"]["c"] += 1
p h["a"]["b"] => 2
p h["a"]["c"] => 1
p h.class => Hash
p h["a"].class => Hash
p h["a"]["b"].class => Fixnum
p h => {}

What's wrong?

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

2. ## Re: Something wrong with my hash of hash

Changing declaration by

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

makes things ok. What are the difference beetween the two declaration?

Lars

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

3. ## Re: Something wrong with my hash of hash

list-bounce@example.com wrote:
> I try to get a hash of hash to make some sort of counter (I have a set
> of random pair and want to count the number of times they
> appear). I use
> this code but even if I can access data, my hash seems empty (so each
> and the others don't work):
>
>
> h =3D Hash.new(Hash.new(0))
> h["a"]["b"] +=3D 1
> h["a"]["b"] +=3D 1
> h["a"]["c"] +=3D 1
> p h["a"]["b"] =3D> 2
> p h["a"]["c"] =3D> 1
> p h.class =3D> Hash
> p h["a"].class =3D> Hash
> p h["a"]["b"].class =3D> Fixnum
> p h =3D> {}
>
>
> What's wrong?
>
> Lars

Try this definition:

h =3D Hash.new { |h, k|
h[k] =3D Hash.new(0)
}

It will actually modify 'h' rather than simply returning and modifying the =
default value.

4. ## Re: Something wrong with my hash of hash

On 10/29/07, Lars Ticot <nicolas.rassat@free.fr> wrote:
> I try to get a hash of hash to make some sort of counter (I have a set
> of random pair and want to count the number of times they appear). I use
> this code but even if I can access data, my hash seems empty (so each
> and the others don't work):
>
>
> h = Hash.new(Hash.new(0))
> h["a"]["b"] += 1
> h["a"]["b"] += 1
> h["a"]["c"] += 1
> p h["a"]["b"] => 2
> p h["a"]["c"] => 1
> p h.class => Hash
> p h["a"].class => Hash
> p h["a"]["b"].class => Fixnum
> p h => {}
>
>
> What's wrong?

You're using the wrong form of Hash.new for this use case.

Hash.new(default)

gives you a hash which simply returns default from [key] when key
doesn't exist, it leaves the hash itself alone.

You need to use a block

h = Hash.new {|h, k| h[k] = Hash.new(0)}
h["a"]["b"] += 1
h["a"]["b"] += 1
h["a"]["c"] += 1
h["a"]["b"] # => 2
h["a"]["c"] # => 1
h.class # => Hash
h # => {"a"=>{"b"=>2, "c"=>1}}
--
Rick DeNatale

My blog on Ruby

5. ## Re: Something wrong with my hash of hash

Lars Ticot wrote:
>> h = Hash.new(Hash.new(0))

> Changing declaration by
> h = Hash.new {|h,k| h[k] = Hash.new(0) }
> makes things ok. What are the difference beetween the two declaration?

There are two differences:
First: The first version executes "Hash.new(0)" once (before the outer
Hash.new is called, since parameters are evaluated before the actual method
call (obviously)) and stores the result as the default value. This means that
if you do something like h[:foo][:chunky] = "bacon" and h[:foo] has not been
assigned before, you will actually change the default value, so h[:bar]
[:chunky] will also be "bacon". The second version just stores the block and
executes it everytime a key that hasn't been assigned before is accessed.

Second: The second version has "h[k] =" in it, so it will not only return the
newly created hash, it will also store it in the outer hash. The first
version won't do that, which means that h will always appear as empty until
you do any actual assignments to it.

HTH,
Sebastian
--
Jabber: sepp2k@jabber.org
ICQ: 205544826

6. ## Re: Something wrong with my hash of hash

Sebastian Hungerecker wrote:

> There are two differences:

[...]

Thanks all of you guys and especially Sebastian for the explanations.

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