Sunday 15 April 2012

ruby - Hashes in hashes that produce default array -



ruby - Hashes in hashes that produce default array -

suppose have:

a = hash.new a['google.com'][:traffic] << 50 a['google.com'][:traffic] << 20 a['google.com'][:popular] << 1 a['google.com'][:popular] << 2 3a['yahoo.com'][:anythinghere] << 3

needs produce this:

a = { 'google.com' => {traffic: [50,20], popular: [1,2]}, 'yahoo.com' => { anythinghere: [3,4] } }

so far i've tried of kind in hope produce result:

a= hash.new(hash.new(array.new))

for example, a['google.com'] produce new hash while a['google.com'][:anythinghere] produce new array. when seek execute above insertions, however, a empty? no thought what's going on, i'm pretty sure i'm missing fundamental here. take look:

a = stats = hash.new(hash.new(array.new)) a['google.com'][:traffic] << 5 a['google.com'][:traffic] << 6 p a['google.com'][:traffic] #=> [5,6] p a['google.com'] #=> empty hash??? p #=> empty hash???

the reason why you're getting unexpected behavior because when pass default value hash argument new, one object default value all keys. example:

s = "but" = hash.new(s) a['x'].concat 't' puts a['y'] # butt puts s # butt

this makes sense since ruby passes objects using pointers, whenever default value it's pointer original object passed.

to work around this, can set default value in block. way hash has reevaluate block every time needs default value:

a = hash.new { "but" } a['x'].concat 't' puts a['x'] # puts a.size # 0

the next gotcha when ruby gets default value, it doesn't assign keys. that's why size of hash still 0 after accessing key in previous example. problem can worked around since ruby supplies hash , missing key default value block, can assignment there:

a = hash.new { |hash, key| hash[key] = "but" } a['x'].concat 't' puts a['x'] # butt puts a['y'] # puts a.size # 2

ruby hash

No comments:

Post a Comment