Issue #10984 has been updated by Olivier Lacan.

Assignee set to Akira Tanaka

Responding to feedback from Akira Tanaka and Nobuyoshi Nakada at [DevelopersMeeting20150514Japan](https://docs.google.com/document/u/1/d/1kEsXwy0X046Z0RqsvWv6O-gJ-tLY91Mc0vDHYZoJE1M/pub)

> akr: °»contain°… is too general. °»subhash°…?

You mean something like this?

```
{ a: 1, b: 2 }.subhash?({ b: 2 })
```

Semantically, this feels strange to me. It doesn't seem obvious at all which hash we're checking for a subhash on and I would expect a lot of confusion with a method name like this. Compare to:

```
{ a: 1, b: 2 }.contains?({ b: 2 })
```

I believe contains is semantically far more self-evident.

It also seems odd to introduce a `sub<class>?` method name for this since I'm not aware of any similar method names for classes that would have similar behavior.

---

> n0kada: °»contain?°… seems similiar to °»include?°…

It is. Sadly, I've been told repeatedly that it's a bad idea to try to change the behavior of `include?`. I would prefer replacing the existing `include?` but I will settle for `contains?` for now because the meaning of "contain" focuses on what's inside the object under observation and is far more commonly used than "comprise": 

~~~
contain |kntn|
verb [ with obj. ]

1. have or hold (someone or something) within: coffee cans that once contained a full pound of coffee.
  - be made up of (a number of things); consist of: borscht can contain mainly beets or a number of vegetables.
  - (of a number) be divisible by (a factor) without a remainder.
~~~

---

> akr: do we really use? we need concrete examples.

Yes, RSpec has an ad-hoc implementation of this feature in its `include` matcher: https://github.com/rspec/rspec-expectations/blob/bb731e29f7800f5cef736cf8850293276a0d3f90/lib/rspec/matchers/built_in/include.rb#L94-L97

RSpec has been downloaded 29 Million times on RubyGems. I think this is a legitimate use case. This would simplify not only RSpec's internal code for Hash matchers, but any existing application who depends on this code, for arelatively minimal impact on the core Hash codebase (see provided patch).

I expanded on my original proposal (since then changed from Hash#include? to Hash#contains?) here: http://olivierlacan.com/posts/proposal-for-a-better-ruby-hash-include/

----------------------------------------
Feature #10984: Hash#contain? to check whether hash contains other hash
https://bugs.ruby-lang.org/issues/10984#change-54696

* Author: Olivier Lacan
* Status: Open
* Priority: Normal
* Assignee: Akira Tanaka
----------------------------------------
Comparing hashes seems like a common practice but there currently isn't a method to ask a 
hash instance whether it includes another hash instance.

The most intuitive method to reach for would be `Hash#include?` but it is in fact an alias to `Hash#has_key?`

What I'm looking for can be achieved with:

~~~
class Hash
  def contain?(other)
    self.merge(other) == self
  end
end
~~~

Here's a simple demo of `#contain?` in use:

~~~
{ a: true, b: false }.contain?({ a: true})
# => true

{ a: true, b: false }.contain?({ b: false})
# => true

{ a: true, b: false }.contain?({ a: false})
# => false

{ a: true, b: false }.contain?({ c: true})
# => false
~~~

One important note is that this method is *not checking for nested hash matches*.
This may need to be addressed when the parameters include a nested hash perhaps.

Thanks to Terence Lee's help, nobu created a patch for this feature last year. 
I've only modified the name of the method from [his original patch](https://gist.github.com/nobu/dfe8ba14a48fc949f2ed) and attached it to this issue.

---Files--------------------------------
Hash#contain_.patch (2.22 KB)


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