[DOC] Adds section "Hash Inclusion" (#12634)

This commit is contained in:
Burdette Lamar 2025-02-10 13:32:25 -06:00 committed by GitHub
parent 7fd589c7fc
commit b4bf3ed130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2025-02-10 19:32:42 +00:00
Merged-By: peterzhu2118 <peter@peterzhu.ca>
2 changed files with 113 additions and 38 deletions

31
doc/hash_inclusion.rdoc Normal file
View File

@ -0,0 +1,31 @@
== \Hash Inclusion
A hash is set-like in that it cannot have duplicate entries
(or even duplicate keys).
\Hash inclusion can therefore based on the idea of
{subset and superset}[https://en.wikipedia.org/wiki/Subset].
Two hashes may be tested for inclusion,
based on comparisons of their entries.
An entry <tt>h0[k0]</tt> in one hash
is equal to an entry <tt>h1[k1]</tt> in another hash
if and only if the two keys are equal (<tt>k0 == k1</tt>)
and their two values are equal (<tt>h0[k0] == h1[h1]</tt>).
A hash may be a subset or a superset of another hash:
- 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+.
- Further, +h0+ is a <i>proper subset</i> of +h1+ (see Hash#<)
if +h1+ is larger than +h0+.
- Superset (including or equal to another):
- \Hash +h0+ is a _superset_ of hash +h1+ (see Hash#>=)
if each entry in +h1+ is equal to an entry in +h0+.
- Further, +h0+ is a <i>proper superset</i> of +h1+ (see Hash#>)
if +h0+ is larger than +h1+.

120
hash.c
View File

@ -3803,21 +3803,29 @@ hash_equal(VALUE hash1, VALUE hash2, int eql)
/*
* call-seq:
* hash == object -> true or false
* self == object -> true or false
*
* Returns whether +self+ and +object+ are equal.
*
* Returns +true+ if all of the following are true:
* * +object+ is a +Hash+ object.
* * +hash+ and +object+ have the same keys (regardless of order).
* * For each key +key+, <tt>hash[key] == object[key]</tt>.
*
* - +object+ is a +Hash+ object (or can be converted to one).
* - +self+ and +object+ have the same keys (regardless of order).
* - For each key +key+, <tt>self[key] == object[key]</tt>.
*
* Otherwise, returns +false+.
*
* Equal:
* h1 = {foo: 0, bar: 1, baz: 2}
* h2 = {foo: 0, bar: 1, baz: 2}
* h1 == h2 # => true
* h3 = {baz: 2, bar: 1, foo: 0}
* h1 == h3 # => true
* Examples:
*
* h = {foo: 0, bar: 1}
* h == {foo: 0, bar: 1} # => true # Equal entries (same order)
* h == {bar: 1, foo: 0} # => true # Equal entries (different order).
* h == 1 # => false # Object not a hash.
* h == {} # => false # Different number of entries.
* h == {foo: 0, bar: 1} # => false # Different key.
* h == {foo: 0, bar: 1} # => false # Different value.
*
* Related: see {Methods for Comparing}[rdoc-ref:Hash@Methods+for+Comparing].
*/
static VALUE
@ -4640,14 +4648,22 @@ hash_le(VALUE hash1, VALUE hash2)
/*
* call-seq:
* hash <= other_hash -> true or false
* self <= other_hash -> true or false
*
* Returns +true+ if +hash+ is a subset of +other_hash+, +false+ otherwise:
* h1 = {foo: 0, bar: 1}
* h2 = {foo: 0, bar: 1, baz: 2}
* h1 <= h2 # => true
* h2 <= h1 # => false
* h1 <= h1 # => true
* Returns +true+ if the entries of +self+ are a subset of the entries of +other_hash+,
* +false+ otherwise:
*
* h0 = {foo: 0, bar: 1}
* h1 = {foo: 0, bar: 1, baz: 2}
* h0 <= h0 # => true
* h0 <= h1 # => true
* h1 <= h0 # => false
*
* See {Hash Inclusion}[rdoc-ref:hash_inclusion.rdoc].
*
* Raises TypeError if +other_hash+ is not a hash and cannot be converted to a hash.
*
* Related: see {Methods for Comparing}[rdoc-ref:Hash@Methods+for+Comparing].
*/
static VALUE
rb_hash_le(VALUE hash, VALUE other)
@ -4659,14 +4675,24 @@ rb_hash_le(VALUE hash, VALUE other)
/*
* call-seq:
* hash < other_hash -> true or false
* self < other_hash -> true or false
*
* Returns +true+ if +hash+ is a proper subset of +other_hash+, +false+ otherwise:
* h1 = {foo: 0, bar: 1}
* h2 = {foo: 0, bar: 1, baz: 2}
* h1 < h2 # => true
* h2 < h1 # => false
* h1 < h1 # => false
* Returns +true+ if the entries of +self+ are a proper subset of the entries of +other_hash+,
* +false+ otherwise:
*
* h = {foo: 0, bar: 1}
* h < {foo: 0, bar: 1, baz: 2} # => true # Proper subset.
* h < {baz: 2, bar: 1, foo: 0} # => true # Order may differ.
* h < h # => false # Not a proper subset.
* h < {bar: 1, foo: 0} # => false # Not a proper subset.
* h < {foo: 0, bar: 1, baz: 2} # => false # Different key.
* h < {foo: 0, bar: 1, baz: 2} # => false # Different value.
*
* See {Hash Inclusion}[rdoc-ref:hash_inclusion.rdoc].
*
* Raises TypeError if +other_hash+ is not a hash and cannot be converted to a hash.
*
* Related: see {Methods for Comparing}[rdoc-ref:Hash@Methods+for+Comparing].
*/
static VALUE
rb_hash_lt(VALUE hash, VALUE other)
@ -4678,14 +4704,22 @@ rb_hash_lt(VALUE hash, VALUE other)
/*
* call-seq:
* hash >= other_hash -> true or false
* self >= other_hash -> true or false
*
* Returns +true+ if +hash+ is a superset of +other_hash+, +false+ otherwise:
* h1 = {foo: 0, bar: 1, baz: 2}
* h2 = {foo: 0, bar: 1}
* h1 >= h2 # => true
* h2 >= h1 # => false
* h1 >= h1 # => true
* Returns +true+ if the entries of +self+ are a superset of the entries of +other_hash+,
* +false+ otherwise:
*
* h0 = {foo: 0, bar: 1, baz: 2}
* h1 = {foo: 0, bar: 1}
* h0 >= h1 # => true
* h0 >= h0 # => true
* h1 >= h0 # => false
*
* See {Hash Inclusion}[rdoc-ref:hash_inclusion.rdoc].
*
* Raises TypeError if +other_hash+ is not a hash and cannot be converted to a hash.
*
* Related: see {Methods for Comparing}[rdoc-ref:Hash@Methods+for+Comparing].
*/
static VALUE
rb_hash_ge(VALUE hash, VALUE other)
@ -4697,14 +4731,24 @@ rb_hash_ge(VALUE hash, VALUE other)
/*
* call-seq:
* hash > other_hash -> true or false
* self > other_hash -> true or false
*
* Returns +true+ if +hash+ is a proper superset of +other_hash+, +false+ otherwise:
* h1 = {foo: 0, bar: 1, baz: 2}
* h2 = {foo: 0, bar: 1}
* h1 > h2 # => true
* h2 > h1 # => false
* h1 > h1 # => false
* Returns +true+ if the entries of +self+ are a proper superset of the entries of +other_hash+,
* +false+ otherwise:
*
* h = {foo: 0, bar: 1, baz: 2}
* h > {foo: 0, bar: 1} # => true # Proper superset.
* h > {bar: 1, foo: 0} # => true # Order may differ.
* h > h # => false # Not a proper superset.
* h > {baz: 2, bar: 1, foo: 0} # => false # Not a proper superset.
* h > {foo: 0, bar: 1} # => false # Different key.
* h > {foo: 0, bar: 1} # => false # Different value.
*
* See {Hash Inclusion}[rdoc-ref:hash_inclusion.rdoc].
*
* Raises TypeError if +other_hash+ is not a hash and cannot be converted to a hash.
*
* Related: see {Methods for Comparing}[rdoc-ref:Hash@Methods+for+Comparing].
*/
static VALUE
rb_hash_gt(VALUE hash, VALUE other)