On Oct 22, 2007, at 5:10 AM, 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..?
>
> T.
>
>

respond_to? + arity it sometimes better.  other alternatices are to  
mark objects with modules

   module Marker; end

   object.extend Marker

   if Marker === object

so you have a more controlled environment - facets could easily use  
this approach.  btw, this is something pervasives addresses and which  
is use quite heavily in meta-programming: for production code i think  
it's best not to ask objects if they do 'x' or 'y' using either  
'respond_to?' OR come 'is_a?' test, rather you should, if possible,  
simply *ensure* that they do.  here is an example

cfp:~ > cat a.rb
class BlankSlate
   instance_methods.each{|m| undef_method m unless m['__']}
end

bs = BlankSlate.new

Object.instance_method('instance_eval').bind(bs).call{ @a = 42 }

class << bs; attr :a; end

p bs.a  #=> 42


cfp:~ > ruby a.rb
42


so, here, we simply *force* the object to 'respond_to?' the method we  
want in exactly the way that we want it to.  this isn't always an  
option but, imho, any general purpose library should at least attempt  
this approach - attributes.rb just just this so as to make the  
smallest amount of assumptions about an objects type/behavior as  
possible.

cheers.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama