[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Hash of arrays - whats going on?

stephen O'D

7/19/2007 9:48:00 PM

I want a hash, where the values of the keys are arrays, eg

h = Hash.new
h.default = []

h['foo'] << 10
h[foo'] << 20
h['bar'] << 23
h['bar'] << 33

I thought this would give me

{ 'foo' => [20 30],
'bar' => [23, 33] }

but it doesn't - it seems to put the same array in the value of each
key. Some googling revealed I need to create my hash like:

h = Hash.new { |hash, key| hash[key] = [] }

So my problem is solved, but why do you have to do it like this? At
the risk of answering my own question, is it because the block is re-
executed everytime you access a non existent key, creating a brand new
array object, while the first way, it just initialises the value to
the same array each time?

Thanks,

Stephen.

2 Answers

Kyle Schmitt

7/19/2007 10:06:00 PM

0

default just lets you return a default value if the request key
doesn't exist, it's not _supposed_ to change the state of the hash.

What was happening is an array was presented to you when you called
h['foo'], and you were putting a value in it, but the array was never
saved to a variable, so it went away.

With the original code try the following code, it may help you understand:
h['foo'] << 10
puts h.length
h[foo'] << 20
puts h.length

Ben Bleything

7/19/2007 10:53:00 PM

0

On Fri, Jul 20, 2007, stephen O'D wrote:
> So my problem is solved, but why do you have to do it like this? At
> the risk of answering my own question, is it because the block is re-
> executed everytime you access a non existent key, creating a brand new
> array object, while the first way, it just initialises the value to
> the same array each time?

The default value you provide is a reference... in this case, you say
"use this array as the default value", not "use an empty array as a
default value". To see what I mean, try this:

empty_ary = []
h = Hash.new
h.default = empty_ary

h['foo'] << 10
puts empty_ary.size

h[foo'] << 20
puts empty_ary.size

h['bar'] << 23
puts empty_ary.size

h['bar'] << 33
puts empty_ary.size

That should show you what's happening.

Ben