I confess to starting down a road and then wondering where it might take me. This may not be the best way of determining if a key/value pair is present in a hash (how could one improve on @Jordan's answer?), but I learned something along the way.
Code
def pair_present?(h,k,v) Enumerable.instance_method(:include?).bind(h).call([k,v]) end
Examples
h = { "a"=>1, "d"=>2, "f"=>35 } pair_present?(h,'a',1) #=> true pair_present?(h,'f',36) #=> false pair_present?(h,'hippopotamus',2) #=> false
Discussion
We could of course convert the hash to an array and then apply Array#include?:
h.to_a.include?(['a', 1]) #=> true
but that has the downside of creating a temporary array. It would be nice if the class Hash had such an instance method, but it does not. One might think Hash#include? might be used for that, but it just takes one argument, a key.1.
The method Enumerable#include? does what we want, and of course Hash includes the Enumerable module. We can invoke that method in various ways.
Bind Enumerable#include? to the hash and call it
This was of course my answer:
Enumerable.instance_method(:include?).bind(h).call([k,v])
Use the method Method#super_method, which was introduced in v2.2.
h.method(:include?).super_method.call(['a',1]) #=> true h.method(:include?).super_method.call(['a',2]) #=> false
Note that:
h.method(:include?).super_method #=> #<Method: Object(Enumerable)#include?>
Do the alias_method/remove_method merry-go-round
Hash.send(:alias_method, :temp, :include?) Hash.send(:remove_method, :include?) h.include?(['a',1]) #=> true h.include?(['a',2]) #=> false Hash.send(:alias_method, :include?, :temp) Hash.send(:remove_method, :temp)
Convert the hash to an enumerator and invoke Enumerable#include?
h.to_enum.include?(['a',1]) #=> true h.to_enum.include?(['a',2]) #=> false
This works because the class Enumerator also includes Enumerable.
1 Hash#include? is the same as both Hash#key? and Hash#has_key?. It makes me wonder why include? isn't used for the present purpose, since determining if a hash has a given key is well-covered.
nil?