On Mar 1, 2007, at 7:03 PM, James Edward Gray II wrote:

> On Mar 1, 2007, at 5:22 PM, Gary Wright wrote:
>
>> On Mar 1, 2007, at 5:30 PM, James Edward Gray II wrote:
>>
>>> I would check for to_hash(), then call that method on the  
>>> argument to get its Hash representation.
>>>
>>
>> That might work but what if the object is an interface to some  
>> sort of database?  You don't
>> really want to convert the external data structure into a Hash  
>> just to access a single item.
>
> OK, what about using Hash#fetch and trapping the IndexError for an  
> invalid key?

Yes, I think #fetch might be a better choice, but not exactly in the  
way you suggest.
I'm thinking specifically about the construction of objects such as:

class A
   def initialize(arg, &b)
   case
   when arg.respond_to?(:nonzero?)
     # do construction based on integer-like behavior
   when arg.respond_to?(:fetch)
     # do construction based on hash-like behavior
   when arg.respond_to?(:to_str)
     # do construction based on string-like behavior
   else
     # punt
   end
end

I was going to use :[] for hash-like behavior but that doesn't sift  
out Integer and Strings so
I started using :has_key?, but that seemed wrong so I posted my  
question.

Your suggestion to use fetch seems promising, but ActiveRecord, for  
example doesn't define
ActiveRecord::Base.fetch.  The correct choice would be find for  
ActiveRecord.  Hash#fetch,
and Array#fetch exist, so that does permit some nice duck-typing  
between those two collections.
RBtree also defines #fetch, which is convenient.

It looks like #fetch might be the best approach.

Gary Wright