Hello. I am new to Ruby. I am more familiar with Python, whose hash
keys are immutable, so I was surprised that Ruby’s were not. When I
try to retrieve a value from a hash after manipulating the associated
key, it returns nil, even though it admits that the key in the hash
and the key I’m passing into the hash’s [] method are the same:
Hello. I am new to Ruby. I am more familiar with Python, whose hash
keys are immutable, so I was surprised that Ruby’s were not. When I
try to retrieve a value from a hash after manipulating the associated
key, it returns nil, even though it admits that the key in the hash
and the key I’m passing into the hash’s [] method are the same:
I’m sure someone has run into this before, but I was unable to find
anything on it. I am using ruby 1.8.5.
Thanks,
DK
ri Hash#rehash
------------------------------------------------------------ Hash#rehash
hsh.rehash -> hsh
Rebuilds the hash based on the current hash values for each key. If
values of key objects have changed since they were inserted, this
method will reindex _hsh_. If +Hash#rehash+ is called while an
iterator is traversing the hash, an +IndexError+ will be raised in
the iterator.
a = [ "a", "b" ]
c = [ "c", "d" ]
h = { a => 100, c => 300 }
h[a] #=> 100
a[0] = "z"
h[a] #=> nil
h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
h[a] #=> 100
=> {[1, 2, 3]=>“test”}
DK
Posted viahttp://www.ruby-forum.com/.
Ah, thank you. Why is this necessary? Isn’t the lookup just a matter
of matching object_id’s?
Remember that hash values are distributed into buckets based on their
key. Change the key, change the bucket.
More precisely if the hash of the key changes the bucket changes. And
since Array calculates it’s hash based on the content changing the
content means changing the key. And, to the OP, lookups in Hashes are
not done via #object_id but via #hash:
More precisely if the hash of the key changes the bucket changes. And
since Array calculates it’s hash based on the content changing the
content means changing the key. And, to the OP, lookups in Hashes are
not done via #object_id but via #hash: Hash table - Wikipedia
which all is necessary in order to have mutable keys, I guess that it
is very difficult to think about that in the beginning when not yet
used to it.
I understand now. I can see how looking up keys by their hash rather
than their object_id is more appropriate.
BTW. I try to avoid to mutate hash keys, I know my limits
Agreed. I was just curious about how things worked underneath.
More precisely if the hash of the key changes the bucket changes. And
since Array calculates it’s hash based on the content changing the
content means changing the key. And, to the OP, lookups in Hashes are
not done via #object_id but via #hash: Hash table - Wikipedia
which all is necessary in order to have mutable keys, I guess that it
is very difficult to think about that in the beginning when not yet
used to it.
Actually it doesn’t spring directly from supporting mutable keys, but
from wanting to have the keys match based on equality rather than
identity.
If Hash used identity instead of hash then
a = “key”.freeze # make the key immutable
h = {a => 1}
h[“key”] ==> nil
even though nothing got mutated.
BTW. I try to avoid to mutate hash keys, I know my limits
Yes if you really want to be safe you can always clone and freeze keys
when inserting into a hash. But that’s probably overkill.
More precisely if the hash of the key changes the bucket changes. And
since Array calculates it’s hash based on the content changing the
content means changing the key. And, to the OP, lookups in Hashes are
not done via #object_id but via #hash: Hash table - Wikipedia
which all is necessary in order to have mutable keys, I guess that it
is very difficult to think about that in the beginning when not yet
used to it.
BTW. I try to avoid to mutate hash keys, I know my limits
Good observation, how is this done in Python than?
I don’t know what goes on under the hood. Because the keys are
immutable, I don’t imagine things like freezing and rehashing are
necessary, but I really don’t know how the keys are looked up.
-DK
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.