开发者

ruby object.hash

What's the meaning of an object's hash value? And in which case does two obj开发者_如何学Goect has the same hash value?? Also it is said that Array|Hash can't be Hash keys, this has something to do with object's hash value, why?


For objects to be stored in hashmaps or hashsets the following must hold true:

If two objects are considered equal, their hash value must also be equal.

If two objects are not considered equal, their hash value should be likely to be different (the more often two different objects have the same hash value, the worse the performance of operations on the hashmap/set).

So if two objects have the same hash value there is a good chance (but no guarantee) that they are equal.

What exactly "equal" means in the above is up to the implementor of the hash method. However you should always implement eql? to use the same definition of equality as hash.

For classes that don't override hash (i.e. classes using Object's hash implementation) hash equality is defined in terms of object identity. I.e. two objects are considered equal if and only if the reside at the same location in memory.

In ruby up to 1.8.6 Array and Hash did not override hash. So if you used arrays (or hashes) as hash keys, you could only retrieve the value for a key, if you used the exact same array as a key for retrieval (not an array with the same contents).

In ruby 1.8.7+ Array#hash and Hash#hash (as well as their eql? methods) are defined so that they are equal when their elements are equal.


A hash value has no inherent meaning, but it is a way of representing that object such that it can be differentiated from other objects of the same type. When you create an object, it needs to implement hash such that if two objects have the same hash value, they will also be equal. What it means for two objects to be equal depends on the object; if you define, say, a Person object, you might want to say that two instances of Person are equal if they have the same name, id number, and birthdate. Or whatever criteria you choose.

Using an array or a hash as a hash key will now work since both do implement hash (such that the hash value is based on their contents). However, you can run into trouble when using a modifiable object such as an array as a key if there's any chance you might modify it. For example, if you have a variable of type Array, and you use it as a key to put something into a hash, and then you add something to the array, and try to use that variable as the key to get the something back out of the hash, it won't work (as the array's hash value has changed). The solution to this issue is to call Rehash on your hash after you modify the array.


What you're looking for is the concept of hashing. It's not just for objects, is a broader concept.


Let's start with basics:

There are 3 things to be considered before understanding Object.hash.

  1. memory address = Address of an Object in RAM.
  2. value = value of an Object.
  3. Type = Type of an Object.

Now let's understand different Object comparison operators.

  1. "eql?" checks if the value of two operands are equal.
  2. "==" checks if the value and type of two operands are the same.
  3. "equal?" checks is this the exact same object?

Example 1: If address of two Object is same then they are pointing to same memory location whose value and Type is same as well.

a="5"
b=a
a.object_id  => 194639
b.object_id  => 194639
a.eql?(b)    => true
a==b         => true
a.equal?(b)  => true

Example 2: Below example demonstrates hash of string and integer "5" is different.

> "5".eql?(5)   => false 
> 5.eql?(5)     => true 
> "5".eql?("5") => true 
> 5.hash        => -3271834327245180286 
> "5".hash      => -3126022673147098896

Conclusion: If value and type of object is same then it will have same hash.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜