From: "mame (Yusuke Endoh) via ruby-core" Date: 2026-02-21T17:56:15+00:00 Subject: [ruby-core:124862] [Ruby Bug#21921] Hash inconsistent ==, >=, <= behavior Issue #21921 has been updated by mame (Yusuke Endoh). The documentation for Hash inclusion is a bit hard to understand due to its mathematical phrasing. > The spec merely says that keys are compared with `==`, but I believe they are actually compared with `eql?` (for normal hashes). The documentation isn't actually saying such a thing. I assume you misread the following sentence: > An entry `h0[k0]` in one hash is equal to an entry `h1[k1]` in another hash if and only if the two keys are equal (`k0 == k1`) and their two values are equal (`h0[k0] == h1[h1]`). This sentence is merely defining the phrase "is equal to". It does not describe the hash lookup mechanism itself. > * Subset (included in or equal to another): > * Hash `h0` is a subset of hash `h1` (see Hash#<=) if each entry in `h0` is equal to an entry in `h1`. This defines the spec of `Hash#<=`. It says that `h0` is a subset of `h1` when every entry (key-value pair) included in `h0` *is equal to* some entry included in `h1`. While the lookup method is not explicitly stated here either, I think it's quite natural to use `h1`'s lookup method when trying to find if those entries exist in `h1`. > 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: That makes sense. However, I don't really think we should change the behavior at the risk of breaking existing working code. ---------------------------------------- Bug #21921: Hash inconsistent ==, >=, <= behavior https://bugs.ruby-lang.org/issues/21921#change-116516 * Author: cohen (Cohen Carlisle) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Hash seems to have very inconsistent behavior for `==`, `>=`, and `<=`. Given that below h1 == h2 is `false` and that they have the same number of keys, I would expect `<=` and `>=` to also be `false`. However, surprisingly `h1 <= h2` and `h2 >= h1` are `true`, while all other permutations are `false`. ``` h1 = {}.compare_by_identity.tap { _1["one"] = 1 } # => {"one" => 1} h2 = {"one" => 1} # => {"one" => 1} h1 == h2 # => false h2 == h1 # => false h1 >= h2 # => false h1 <= h2 # => true h2 >= h1 # => true h2 <= h1 # => false ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/