Hi --
> 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.
That's interesting. It makes me wonder if it's worth "hardening" with
something like:
respond_to?(:meta, OpenURI::Meta)
So that Ruby will check that it would respond to a #meta that's
defined in OpenURI. But yea, really, I agree with you. I never really
realized it before, but respond_to? is pretty weak.
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.
Sort-of, but it wraps the singleton in a Functor, so you can call
methods against it as if you had opened it up yourself. For example:
class X
meta.attr :x
end
Defines a class attribute.
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.
Indeed.
T.
···
On Oct 22, 7:29 am, "David A. Black" <dbl...@wobblini.net> wrote:
On Mon, 22 Oct 2007, Trans wrote: