Hi --

On Mon, 22 Oct 2007, Trans wrote:

> Hi--
>
> I recently cam across an interesting conflict between open-uri.rb and
> Facets rendition of kernel/metaid.rb. Facets defines a general
> extension Kernel#meta, and open-uri defines OpenURI::Meta#meta. open-
> uri uses OpenURI::Meta to extend StringIO via singleton. This is all
> fine, but then open-uri checks to see if a StringIO object has been
> extended by doing:
>
>  io.respond_to? :meta
>
> And that's where the problem lies, b/c if you've loaded 'facets/kernel/
> metaid' you're going to get a false positive here. Now the best remedy
> is open-uri to be more precise:
>
>  io.is_a? OpenURI::Meta
>
> That fixes the the problem. But it raises an interesting question.
> I've used #respond_to? myself from time to time thinking it was oh, so
> duck-type kosher; never realizing that it might clash with general
> extensions.
>
> So where lies the fault in this conflict? Are extensions the bad guy,
> or is respond_to? really not a good oop concept? Or..?

I think this is just the age-old issue about adding methods to
existing classes and hitting conflicts. #respond_to? is relatively
dumb; it can't tell you what the method actually does. I think of it
as an important tool for "soft" duck typing, in contrast with "hard"
duck typing where you just send the object the message.

What does your Kernel#meta do? If it's what's usually called
#singleton_class, you might change it to #singleton_class :-) Or
something like that (#metaclass, if you're into that terminology) -- a
little more descriptive and less likely to clash. There's no perfect
solution, though. Using #extend on specific objects, instead of adding
methods to Kernel, could make clashes much less likely, though if you
happened to add #meta to a StringIO object via #extend, you'd still
have the same problem.


David

-- 
Upcoming training from Ruby Power and Light, LLC:
   * Intro to Ruby on Rails, Edison, NJ, October 23-26
   * Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!