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