I often find that when writing initialize (or alternate constructors)
I want to examine the class of the arguments to decide how to
proceed. An example is Array.new, which behaves differently if it
is given an integer argument or an array argument:
Array.new 2 # [nil,nil] Array.new [1,2] # [1,2]
These sorts of tests can be done via Class#=== or Kernel#is_a? or
Kernel#kind_of? but that can lead to artificial constraints. Using
Kernel#respond_to? seems to avoid many of those constraints.
My question is: What is the least constraining test to determine
if you’ve got a hash-like object? Is arg.respond_to?(:has_key?)
reasonable? At first I thought a test for : would be great but
that catches strings also. I’m thinking that if someone hands my
method a Hash or a HashWithIndifferentAccess or an OrderedHash or
a tree of some sort, I’d like to be able to accept all of them.
All I really want to know is “Does this object provide key/value
pair lookups via the # method?”, but I don’t want to get strings
and integers along for the ride (for example).