Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Conflicts between using respond_to? and extending Ruby

Reply
Thread Tools

Conflicts between using respond_to? and extending Ruby

 
 
Trans
Guest
Posts: n/a
 
      10-22-2007
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.


 
Reply With Quote
 
 
 
 
David A. Black
Guest
Posts: n/a
 
      10-22-2007
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!

 
Reply With Quote
 
 
 
 
Trans
Guest
Posts: n/a
 
      10-22-2007


On Oct 22, 7:29 am, "David A. Black" <(E-Mail Removed)> wrote:
> 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.


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
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.


 
Reply With Quote
 
Stefan Rusterholz
Guest
Posts: n/a
 
      10-22-2007
Trans wrote:
> respond_to?(:meta, OpenURI::Meta)


I'm sorry, but that looks just so wrong to me. Take the case on .each.
You don't test if an object respond_to?(:each, Enumerable), you just
need the .each.
I don't think there's a solution to the problem as you sacrifice one or
the other thing. You can't know by the name of a method whether it does
what you want or not. So either you jump into the cold water and assume
it does or you sacrifice flexibility and test if it's derived from
something you know.

Regards
Stefan
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      10-22-2007
On 10/22/07, David A. Black <(E-Mail Removed)> wrote:

> On Mon, 22 Oct 2007, Trans wrote:


> > 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.


Okay, I'm claiming stake to coining what I hope becomes as much of a
meme as duck typing:

http://talklikeaduck.denhaven2.com/a...nt-duck-typing


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      10-22-2007
Hi --

On Mon, 22 Oct 2007, Rick DeNatale wrote:

> On 10/22/07, David A. Black <(E-Mail Removed)> wrote:
>
>> On Mon, 22 Oct 2007, Trans wrote:

>
>>> 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.

>
> Okay, I'm claiming stake to coining what I hope becomes as much of a
> meme as duck typing:
>
> http://talklikeaduck.denhaven2.com/a...nt-duck-typing


Be careful what you wish for In any case, I'm glad to have
provided the impetus, if not the name.

What I've always called the soft/hard duck typing distinction isn't
quite the same as what you're calling the chicken/duck distinction,
though, in the sense that I rule is_a? and kind_of? completely out of
bounds as duck typing of any kind. Duck typing, as I understand it
from various writings by, and exchanges with, Dave Thomas, starts
where is_a? leaves off. respond_to? starts to enter the duck-typing
orbit, in the sense that at least it's focused on the object and its
capabilities, rather than its class/module ancestry (and that's the
most decisive line to cross). Since it still falls short of simply
asking the object to do something, I consider it a "soft" form of duck
typing. It's object-driven, but not atomic.


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing with Rails, Edison, NJ, November 6-9
* Advancing with Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      10-22-2007
Hi --

On Mon, 22 Oct 2007, David A. Black wrote:

> What I've always called the soft/hard duck typing distinction isn't
> quite the same as what you're calling the chicken/duck distinction,
> though, in the sense that I rule is_a? and kind_of? completely out of
> bounds as duck typing of any kind.


I didn't put that very clearly, since you do too. What I mean is, it's
like this:


Rick:

Chicken-typing
is_a?/kind_of?
respond_to?
Duck-typing
obj.message

David:

Class-checking:
is_a?/kind_of
Soft duck:
respond_to?
Hard duck:
obj.message


or something.


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing with Rails, Edison, NJ, November 6-9
* Advancing with Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!

 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      10-22-2007
On 10/22/07, David A. Black <(E-Mail Removed)> wrote:

> What I've always called the soft/hard duck typing distinction isn't
> quite the same as what you're calling the chicken/duck distinction,
> though, in the sense that I rule is_a? and kind_of? completely out of
> bounds as duck typing of any kind. Duck typing, as I understand it
> from various writings by, and exchanges with, Dave Thomas, starts
> where is_a? leaves off. respond_to? starts to enter the duck-typing
> orbit, in the sense that at least it's focused on the object and its
> capabilities, rather than its class/module ancestry (and that's the
> most decisive line to cross). Since it still falls short of simply
> asking the object to do something, I consider it a "soft" form of duck
> typing. It's object-driven, but not atomic.


One difference between kind_of? and respond_to? is that it's slightly
more likely that a particular method or methods mean what the chicken
typer expects when using kind_of? than respond_to?, since kind_of? is
testing an implementation relationship, but that's by no means
guaranteed.

The notion of 'type' held by the user of an object is often more
complex and or general than just being in a particular implementation
hierarchy, or responding to a certain set of verbs at the lexical
level. So I don't see so much of a distinction between respond_to?
and kind_of?

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      10-22-2007
Hi --

On Tue, 23 Oct 2007, Rick DeNatale wrote:

> On 10/22/07, David A. Black <(E-Mail Removed)> wrote:
>
>> What I've always called the soft/hard duck typing distinction isn't
>> quite the same as what you're calling the chicken/duck distinction,
>> though, in the sense that I rule is_a? and kind_of? completely out of
>> bounds as duck typing of any kind. Duck typing, as I understand it
>> from various writings by, and exchanges with, Dave Thomas, starts
>> where is_a? leaves off. respond_to? starts to enter the duck-typing
>> orbit, in the sense that at least it's focused on the object and its
>> capabilities, rather than its class/module ancestry (and that's the
>> most decisive line to cross). Since it still falls short of simply
>> asking the object to do something, I consider it a "soft" form of duck
>> typing. It's object-driven, but not atomic.

>
> One difference between kind_of? and respond_to? is that it's slightly
> more likely that a particular method or methods mean what the chicken
> typer expects when using kind_of? than respond_to?, since kind_of? is
> testing an implementation relationship, but that's by no means
> guaranteed.
>
> The notion of 'type' held by the user of an object is often more
> complex and or general than just being in a particular implementation
> hierarchy, or responding to a certain set of verbs at the lexical
> level. So I don't see so much of a distinction between respond_to?
> and kind_of?


The distinction I see is proximity to the object. respond_to? is
asking the object about its capabilities, whereas kind_of? is asking
it about its ancestry. So respond_to? is a tighter fit with the object
as it is at a given point in runtime.


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing with Rails, Edison, NJ, November 6-9
* Advancing with Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!

 
Reply With Quote
 
ara.t.howard
Guest
Posts: n/a
 
      10-22-2007

On Oct 22, 2007, at 10:39 AM, David A. Black wrote:

> The distinction I see is proximity to the object. respond_to? is
> asking the object about its capabilities, whereas kind_of? is asking
> it about its ancestry. So respond_to? is a tighter fit with the object
> as it is at a given point in runtime.


it all depends - consider the case of trying to tell wether or not a
hash, array, or rbtree is passed to a method. you can't use
'respond_to?("[]")', 'respond_to?("size")', etc. you can sometimes
pick the 'right' method but, other times you cannot and

case obj
when Array
...

is safer and more accurate. i think it really depends on the use
case - i personally use both.

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




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Extending Ruby using C++ and Rice Lea Savage Ruby 2 04-20-2010 02:45 PM
conflicts with file from package ruby-libs 15characters 15characters Ruby 0 06-06-2009 07:45 PM
ruby macro bind conflicts tr1 on msvc9.0 Christoph Heindl Ruby 0 01-17-2009 09:25 AM
formsauthentication conflicts between 2 aspx apps Sarah ASP .Net 1 11-04-2005 03:19 PM
Conflicts between Firefox and Adobe? J Firefox 6 01-03-2005 12:18 PM



Advertisments