Gary Wright
3/2/2007 12:32:00 AM
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