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!