From: merch-redmine@...
Date: 2020-05-12T17:48:36+00:00
Subject: [ruby-core:98291] [Ruby master Bug#16850] Object#hash doesn't	behave as documented

Issue #16850 has been updated by jeremyevans0 (Jeremy Evans).


I consider this an implementation detail. It never makes sense to override the hash calculation for the cases where Ruby uses the built-in calculation instead of calling #hash, so I don't think Ruby should change behavior to increase consistency.  However, we could explicitly document the behavior.  Something like:

```diff
diff --git a/hash.c b/hash.c
index e75a431c09..b7d320f7c2 100644
--- a/hash.c
+++ b/hash.c
@@ -315,6 +315,9 @@ objid_hash(VALUE obj)
  * implementations of Ruby.  If you need a stable identifier across Ruby
  * invocations and implementations you will need to generate one with a custom
  * method.
+ *
+ * Certain core classes such as Integer use built-in hash calculations and
+ * do not call the #hash method when used as a hash key.
  *--
  * \private
  *++
```

Thoughts on that?

----------------------------------------
Bug #16850: Object#hash doesn't behave as documented
https://bugs.ruby-lang.org/issues/16850#change-85530

* Author: ana06 (Ana Maria Martinez Gomez)
* Status: Open
* Priority: Normal
* ruby -v: master
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
From [Ruby 2.7 Object class documentation](https://ruby-doc.org/core-2.7.0/Object.html#method-i-hash):
>The hash value is used along with eql? by the Hash class to determine if two objects reference the same hash key.

From this I expect that overwritting the `Object#hash` method changes the Hashing algorithm. But this is only the case for some objets. Consider the following code:

```Ruby
class Object
  def hash
    i_dont_exist
  end 
end

class Ana 
end

hash = {}
hash[3] = true
hash[3] = false
puts 'Integers are not using the new hash method'
hash[Ana.new] = true
puts 'this will not be executed because the class Ana uses the new hash method'
```

The output of executing this code is:
```
Integers are not using the new hash method
Traceback (most recent call last):
        1: from a.rb:13:in `<main>'
a.rb:3:in `hash': undefined local variable or method `i_dont_exist' for #<Ana:0x000055626f0b7a30> (NameError)
```

This proves that Integer hash method is not used to determine if two objects reference the same hash key, as said in the documentation. Check the [`any_hash` method](https://github.com/ruby/ruby/blob/master/hash.c#L188) for the other classes affected.

I think that either the behavior should be modified (aiming for a consistency along different classes and following the documentation) or the documentation updated.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>