This has not affected any real-world app I use. I noticed this while working on a bidirectional hash gem (bihash@rubygems).
However, I don't think the behavior is consistent with the spec as written:
The spec merely says that keys are compared with ==, but I believe they are actually compared with eql? (for normal hashes).
If keys were just compared with ==, all the above comparisons would return true.
I think the spec could also be improved in other ways, assuming there will be no behavioral change:
The spec doesn't mention that before comparison, keys must first be found via the supposedly larger hash's lookup method.
E.g., In h1 <= h2, keys from h1 are looked up in h2 using h2's lookup method, so when h2 is a normal hash it finds the key, but when h2 is an identity hash it fails.
The crux of this issue seems to be that the lookup method differs between identity and normal hashes, which isn't mentioned in the spec.
Raising when comparing identity and normal hashes could also work, but I would expand that raise to include < and >, since they suffer the same problems:
h1 = {}.compare_by_identity
h2 = {}
h1["one"] = 1 # h1 = {"one" => 1}.compare_by_identity
h2["one"] = 1
h2["two"] = 2 # h2 = {"one", "two" => 2}
h1 < h2 # => true
h2 > h1 # => true
h1 = {}
h2 = {}.compare_by_identity
h1["one"] = 1 # h1 = {"one" => 1}
h2["one"] = 1
h2["two"] = 2 # h2 = {"one", "two" => 2}.compare_by_identity
h1 < h2 # => false (surprising, different than above)
h2 > h1 # => false (surprising, different than above)
I think there are actually three interrelated issues here:
- When comparing for inclusion, hashes take keys from the maybe smaller hash and look them up in the maybe larger hash, yielding inconsistent results when identity and normal hashes mix (original and newest example).
- The equality semantics of inclusion are different from
Hash#== semantics, leading to further confusion (original example).
- The inclusion specs don't seem consistent with the current behavior and the method/operator docs could call this out more strongly.