From: Gary Wright Date: 2007-03-02T09:31:47+09:00 Subject: Re: Duck Typing Hash-Like Objects 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