diff --git a/doc/hash_inclusion.rdoc b/doc/hash_inclusion.rdoc new file mode 100644 index 0000000000..05c2b0932a --- /dev/null +++ b/doc/hash_inclusion.rdoc @@ -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 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]). + +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 proper subset 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 proper superset of +h1+ (see Hash#>) + if +h0+ is larger than +h1+. + diff --git a/hash.c b/hash.c index 3ba5b43282..55352e562f 100644 --- a/hash.c +++ b/hash.c @@ -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+, hash[key] == object[key]. + * + * - +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+, self[key] == object[key]. * * 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)