Upon inspection of ‘a’, it sure seems that it’s empty, but upon
inspection of the key, it does have a value attached to it! Can we trust
this? Expected / unexpected behavior ?
Upon inspection of ‘a’, it sure seems that it’s empty, but upon
inspection of the key, it does have a value attached to it! Can we trust
this? Expected / unexpected behavior ?
Upon inspection of ‘a’, it sure seems that it’s empty, but upon
inspection of the key, it does have a value attached to it! Can we trust
this? Expected / unexpected behavior ?
Reminder : a = Hash.new(Hash.new)
The default argument to a hash gets returned when the key is not
found, but not added to the hash. The logic is more or less
def
if self.contains(key):
return self.value_of(key)
else
return default
end
What you want is the block version, which accepts the hash itself and
the key as parameters, and lets you do the right thing, here
a = Hash.new {|hash, key| hash[key] = Hash.new}
a = Hash.new {|hash, key| hash[key] = Hash.new}
=> {}
a[5]
=> {}
a
=> {5=>{}}
Upon inspection of ‘a’, it sure seems that it’s empty, but upon
inspection of the key, it does have a value attached to it! Can we trust
this? Expected / unexpected behavior ?
Maybe this might explain the behavior a bit more clearly:
>> d = Hash.new
=> {}
>> a = Hash.new(d)
=> {}
>> a[5][4] = 3
=> 3
>> a
=> {}
>> a[5]
=> {4=>3}
>> a[6]
=> {4=>3}
>> d
=> {4=>3}
Notice that the default value for hash a (the other hash) has changed.
And you’ve already noticed that the hash just appears to have values
when queried specifically, but not when inspected.
You probably want to declare the hash as Hash.new { |h, k| h[k] =
{} }
IMHO this solution is even simpler because it does not need the method:
h = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
Robert - I agree. I like this one better. Feels a little more ruby-ish.
Is there a way to use Proc (or whatever does work) to save this block
and reuse it when creating a new hash ?
Something like :
a = Proc.new {|h,k| h[k] = Hash.new(&h.default_proc)}
b = Hash.new a
Note, I know this is wrong… It’ll just put the proc as the default
value, instead of triggering the proc.
IMHO this solution is even simpler because it does not need the method:
h = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
Robert - I agree. I like this one better. Feels a little more ruby-ish.
Is there a way to use Proc (or whatever does work) to save this block
and reuse it when creating a new hash ?
The block is saved and reused when creating nested Hashes!
Something like :
a = Proc.new {|h,k| h[k] = Hash.new(&h.default_proc)}
b = Hash.new a
Note, I know this is wrong… It’ll just put the proc as the default
value, instead of triggering the proc.
Robert - I agree. I like this one better. Feels a little more ruby-ish.
instead of triggering the proc.
Maybe this is his use case?
If I wanted to save typing I’d place the whole construction in a method
def cnh # silly name “create nested hash”
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
Robert - I agree. I like this one better. Feels a little more ruby-ish.
instead of triggering the proc.
Maybe this is his use case?
If I wanted to save typing I’d place the whole construction in a method
def cnh # silly name “create nested hash”
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
a = cnh
b = cnh
c = cnh
d = cnh
Kind regards
robert
Oh sure - be lazier than me. I see how it is.
Thanks - Jesus was right… I was trying to be lazy.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.