From: brian ford Date: 2009-06-11T02:34:36+09:00 Subject: [ruby-core:23788] Re: Ducktyping interface Hi, On Sat, Jun 6, 2009 at 5:30 PM, Yehuda Katz wrote: > I should add that further examination reveals that people who make proxy > objects (Drb, Rails Association Proxy) expect that their respond_to? will > work correctly. If implementations were allowed to do internal checks only, > proxies would need to explicitly define all coercion methods, something they > do not currently do. > -- Yehuda The more I've thought about this the more I am convinced that MRI calling #respond_to? is an implementation detail that code has unfortunately relied on. I want to strongly advocate for not making this part of a defined Ruby ducktyping interface that alternate implementations must adhere to. Basically, it comes down to this: Why override #respond_to? when all you should really have to do is define a #method_missing if you don't want to define e.g. the #to_s method? Requiring that #respond_to? returns true before the implementation code will call the method actually removes dynamism from code since the normal mechanism is to dispatch to #method_missing if the called method is not reached. (Evan Phoenix pointed this out.) To put this in perspective, it is broadly considered a code smell if Ruby code calls #kind_of? or (slightly less) #respond_to? a lot. That is simply not good OO design where objects present an interface based on the methods they define (or #method_missing). Why should that standard be different for the Ruby implementation? None of the "real world" code examples presented really justify requiring that #respond_to? be called. Instead, they illustrate this unfortunate implementation details. They can be made to work just by _removing_ the (unnecessary) #respond_to? override. Thanks, Brian > > On Sat, Jun 6, 2009 at 5:12 PM, Yehuda Katz wrote: >> >> Matz, >> I've been working on adding some specs to RubySpec related to the >> ducktyping interface. I have observed the following behavior and want to >> know whether or not it's intentional. Let's use the #to_s coercion as an >> example: >> 1. If the object has a method #to_s, it's called. >> 2. If #to_s returns something that is not a String, a TypeError is >> raised. >> In MRI, the mechanism for determining if an object has a method #to_s is >> to call respond_to?. This means that even if the method does not exist, >> #to_s will get called, and fall through to #method_missing, if the >> #respond_to method returns true for :to_s. As a result, when using MRI, it >> is possible to implement the duck-typing interface without defining #to_s, >> but instead defining a combination of #respond_to? and #method_missing that >> returns a String. >> Is this intentional? Would it be ok for an alternative implementation to >> look up the #to_s method using an internal check instead of calling the >> user-defined #respond_to?, as MRI does? >> In other words, is the only "correct" way to enlist in Ruby coercion to >> define to_s explicitly, or is another correct way to define respond_to? and >> method_missing to return an appropriate response? >> -- >> Yehuda Katz >> Developer | Engine Yard >> (ph) 718.877.1325 > > > > -- > Yehuda Katz > Developer | Engine Yard > (ph) 718.877.1325 >