<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-8840979806248747743.post3020389393451158861..comments</id><updated>2008-03-03T18:19:08.848-08:00</updated><category term='ruby'/><category term='feeds'/><category term='Windows XP'/><category term='Vista'/><category term='education'/><category term='NWEN'/><category term='Microsoft'/><category term='product support'/><category term='debugging'/><category term='gadgets'/><category term='Amazon'/><category term='web applications'/><category term='competition'/><category term='privacy'/><category term='source code control'/><category term='open source'/><category term='algorithms'/><category term='public speaking'/><category term='Azure'/><category term='fundraising'/><category term='dogfood'/><category term='outsourcing'/><category term='memcache'/><category term='beachware'/><category term='prototyping'/><category term='python'/><category term='performance'/><category term='self hosting'/><category term='learning'/><category term='pipes'/><category term='app engine'/><category term='EC2'/><category term='blogs'/><category term='hardware'/><category term='startups'/><category term='presentations'/><category term='work/life balance'/><category term='StartPad'/><category term='business plans'/><category term='jQuery'/><category term='cloud computing'/><category term='schedules'/><category term='security'/><category term='politics'/><category term='typing'/><category term='best practices'/><category term='entrepreneurship'/><category term='backups'/><category term='puzzazz'/><category term='networking'/><category term='shipping'/><category term='30 day startup'/><category term='C#'/><category term='passion'/><category term='Microsoft Windows'/><category term='petitions'/><category term='consistency'/><category term='priorities'/><category term='software projects'/><category term='Django'/><category term='languages'/><category term='quality'/><category term='project management'/><category term='investors'/><category term='google'/><title type='text'>Comments on thisDev: The Myth of Duck Typing</title><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.thisdev.com/feeds/3020389393451158861/comments/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html'/><author><name>Roy Leban</name><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-8078525317827607768</id><published>2008-03-03T18:19:00.000-08:00</published><updated>2008-03-03T18:19:00.000-08:00</updated><title type='text'>The main distinction between Duck typing and inter...</title><content type='html'>The main distinction between Duck typing and interfaces is that objects can guarantee that they respond to a "contract"; i.e., a whole collection of methods, rather than a single one.  I also think your example is a little artificial - I don't generally want the compiler arbitrarily choosing among multiple interfaces to an object.  And even when it does, you're most likely going to have conditional code based on the type of interface you got.&lt;BR/&gt;&lt;BR/&gt;Real systems are generally built with specific implementations in mind; certainly they have to be tested against specific implementations.  I have always felt that building "plugable" interfaces that work across unknown implementations is an elusive goal.  The only places it's been done successfully is when a) one side of the implementation has an established standard against which to test, and b) the interfaces are kept very simple.&lt;BR/&gt;&lt;BR/&gt;I think Microsoft's experiment with OLE (and Apple's experiment with AppleScript) has shown the fragility of trying to integrate highly complex objects exposing a myriad of interfaces.&lt;BR/&gt;&lt;BR/&gt;By the way, your example brought to mind the elegant way that Prototype (javascript library) handled returning an interface to the XMLHttpRequest object:&lt;BR/&gt;&lt;BR/&gt;var Ajax = {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;getTransport: function() {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Try.these(&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function() {return new XMLHttpRequest()},&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function() {return new ActiveXObject('Msxml2.XMLHTTP')},&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;function() {return new ActiveXObject('Microsoft.XMLHTTP')}&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;) || false;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;},&lt;BR/&gt;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;activeRequestCount: 0&lt;BR/&gt;}&lt;BR/&gt;&lt;BR/&gt;var Try = {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;these: function() {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var returnValue;&lt;BR/&gt;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (var i = 0, length = arguments.length; i &lt; length; i++) {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var lambda = arguments[i];&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try {&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;returnValue = lambda();&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} catch (e) {}&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR/&gt;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return returnValue;&lt;BR/&gt;&amp;nbsp;&amp;nbsp;}&lt;BR/&gt;}&lt;BR/&gt;&lt;BR/&gt;Note that it's important to control the order in which each interface is selected - a built in language feature would not necessarily control that for you.  I think the Try.these() paradigm is a good one for wrapping Duck typed object of unknown origin.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/8078525317827607768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/8078525317827607768'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204597140000#c8078525317827607768' title=''/><author><name>Mike Koss</name><uri>http://www.blogger.com/profile/16991627140888922439</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://mckoss.com/images/mycryptos.jpg'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1867078891'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-1089375699965657630</id><published>2008-03-02T07:33:00.000-08:00</published><updated>2008-03-02T07:33:00.000-08:00</updated><title type='text'>Good post.&lt;br&gt;&lt;br&gt;I started in Smalltalk which I l...</title><content type='html'>Good post.&lt;BR/&gt;&lt;BR/&gt;I started in Smalltalk which I loved for a long time.  When Java started on the scene I saw the benefits of strong typing that you support in your post.  But after using Java for the past 7 years, I am loving the comeback of dynamic typing languages like Scala.   &lt;BR/&gt;&lt;BR/&gt;This is really one of those arguments that is totally subjective and hence can't be won.  &lt;BR/&gt;&lt;BR/&gt;To each his/her own.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/1089375699965657630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/1089375699965657630'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204471980000#c1089375699965657630' title=''/><author><name>Mike Witters</name><uri>http://www.blogger.com/profile/13237611245541305054</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1675339670'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-2600212820828954643</id><published>2008-03-01T10:24:00.000-08:00</published><updated>2008-03-01T10:24:00.000-08:00</updated><title type='text'>I can't resist to bring this to notice: &lt;a href="h...</title><content type='html'>I can't resist to bring this to notice: &lt;A HREF="http://scala.sygneca.com/patterns/duck-typing-done-right" REL="nofollow"&gt;Duck typing done right&lt;/A&gt;.&lt;BR/&gt;Scala is very promising :)</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2600212820828954643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2600212820828954643'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204395840000#c2600212820828954643' title=''/><author><name>Gabriel C.</name><uri>http://www.blogger.com/profile/17525961934302794120</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://bp1.blogger.com/_skxdtFBr4vU/RpOblxQZxBI/AAAAAAAAAB0/30w9xoZhcMk/s320/Imagen024b.jpg'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-2137856721'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-8976937925768896091</id><published>2008-02-29T13:56:00.000-08:00</published><updated>2008-02-29T13:56:00.000-08:00</updated><title type='text'>Final comment: the idea of a compile time is incom...</title><content type='html'>Final comment: the idea of a compile time is incompatible with Ruby as currently implemented!&lt;BR/&gt;&lt;BR/&gt;And if you are concerned about code being changed, you should be running tests, which IMHO, are the only way to ensure that your code doesn't modify itself and remove a needed method at runtime. Like I said, Java can do it via reflection, even C can do it via twiddling with the dispatch table.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/8976937925768896091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/8976937925768896091'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204322160000#c8976937925768896091' title=''/><author><name>Jim</name><uri>http://www.blogger.com/profile/00964727644098022520</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-42971834'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-3616253451182837216</id><published>2008-02-29T13:50:00.000-08:00</published><updated>2008-02-29T13:50:00.000-08:00</updated><title type='text'>Rob: I also forgot to mention that if you want int...</title><content type='html'>Rob: I also forgot to mention that if you want interfaces, then you should be using a mixin. So to implement obj.render, I'd want to implement a mixin for the different types of rendering.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3616253451182837216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3616253451182837216'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204321800000#c3616253451182837216' title=''/><author><name>Jim</name><uri>http://www.blogger.com/profile/00964727644098022520</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-42971834'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-7310405689120471980</id><published>2008-02-29T13:47:00.000-08:00</published><updated>2008-02-29T13:47:00.000-08:00</updated><title type='text'>Jorge: Just wanted to point out that you cannot ch...</title><content type='html'>Jorge: Just wanted to point out that you cannot change the type of an object at runtime. You can change it's methods, which is unrelated to duck-typing. Using reflection, I can do that in Java. You can change the variable's type, except that variables don't have type. Only objects have type.&lt;BR/&gt;&lt;BR/&gt;Rob: I agree that this type of respond_to? chaining is wrong. But I think that a better technique would be to define a render method and call obj.render, and let the object do it's rendering. But that's just me</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/7310405689120471980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/7310405689120471980'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204321620000#c7310405689120471980' title=''/><author><name>Jim</name><uri>http://www.blogger.com/profile/00964727644098022520</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-42971834'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-7113276427366238002</id><published>2008-02-29T12:34:00.000-08:00</published><updated>2008-02-29T12:34:00.000-08:00</updated><title type='text'>&lt;b&gt;commons_guy&lt;/b&gt;: I don't agree it's a strawman....</title><content type='html'>&lt;B&gt;commons_guy&lt;/B&gt;: I don't agree it's a strawman. This is a real case. I have a list of objects (of unknown types) and render them. Many of the classes I create support to_html, but not all of them. Why shouldn't I be able to handle it gracefully?&lt;BR/&gt;&lt;BR/&gt;Your implementation below doesn't have the same functionality as my examples. Make it match and I'll gladly post it in an update with proper formatting (why doesn't Blogger support the pre tag in comments?). And you're using nil as a magic value. What if the methods we're calling return nil as a valid result? Neither of the examples have a problem with that.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/7113276427366238002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/7113276427366238002'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204317240000#c7113276427366238002' title=''/><author><name>Roy Leban</name><uri>http://www.blogger.com/profile/08749140682886637193</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-225288892'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-2364731193469600709</id><published>2008-02-29T12:23:00.000-08:00</published><updated>2008-02-29T12:23:00.000-08:00</updated><title type='text'>"But when I know I need a particular interface (no...</title><content type='html'>"But when I know I need a particular interface (not a class), why can't I tell the compiler so it can enforce it?"&lt;BR/&gt;&lt;BR/&gt;Because any such type-checking at compile-time would be useless. Suppose class C implements interface I at compile-time. At run-time, however, I dynamically remove a method from class C, such that it no longer implements I. Then all your compile-time type-checking is rendered useless.&lt;BR/&gt;&lt;BR/&gt;I'm not against compile-time type-checking. I just think it is fundamentally incompatible with Ruby's goals and philosophy. (It's one of the reasons I don't use Ruby.)</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2364731193469600709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2364731193469600709'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204316580000#c2364731193469600709' title=''/><author><name>Jorge Ortiz</name><uri>http://www.blogger.com/profile/14454965475839432618</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1962474094'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-3781310492665536851</id><published>2008-02-29T12:19:00.000-08:00</published><updated>2008-02-29T12:19:00.000-08:00</updated><title type='text'>"And as for those strings read in from the command...</title><content type='html'>"And as for those strings read in from the command line that get evaled? Great idea for a dev tool. Bad idea for a server. Ever hear of "SQL Injection"?"&lt;BR/&gt;&lt;BR/&gt;$SAFE should cover you in many cases. Bear in mind that some Ruby templating engines use eval() to achieve their ends.&lt;BR/&gt;&lt;BR/&gt;"Here's a challenge. Write your version of render(obj) that doesn't use respond_to and has the same functionality"&lt;BR/&gt;&lt;BR/&gt;I'd call a render(obj) method that isn't told what it's supposed to be rendering a code smell. You've created a straw man, then are trying to make your point by claiming it's made of straw.&lt;BR/&gt;&lt;BR/&gt;Moreover, your alternate implementation is indeterminate for objects that implement multiple interfaces (e.g., IConvertsToHTML &lt;B&gt;and&lt;/B&gt; IConvertsToJSON).&lt;BR/&gt;&lt;BR/&gt;But, since you insist...and forgive the probably awful formatting from Blogger's edit pane:&lt;BR/&gt;&lt;BR/&gt;def send_or_nil(obj, msg)&lt;BR/&gt;  begin&lt;BR/&gt;    obj.send(msg)&lt;BR/&gt;  rescue NoMethodError&lt;BR/&gt;    nil&lt;BR/&gt;  end&lt;BR/&gt;end&lt;BR/&gt;&lt;BR/&gt;def render(obj)&lt;BR/&gt;  result=nil&lt;BR/&gt;&lt;BR/&gt;  [:to_html, :to_json].each do |m|&lt;BR/&gt;    result=send_or_nil(obj, m)&lt;BR/&gt;    break if result&lt;BR/&gt;  end&lt;BR/&gt;&lt;BR/&gt;  result ? result : obj.to_s&lt;BR/&gt;end&lt;BR/&gt;&lt;BR/&gt;You might consider moving the array of symbols somewhere that'll be easier to find. You could open Object and implement send_or_nil() on it instead of having it in whatever class implements render().</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3781310492665536851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3781310492665536851'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204316340000#c3781310492665536851' title=''/><author><name>commons_guy</name><uri>https://me.yahoo.com/commons_guy#7a35d</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/openid16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-717471790'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-6563220170331002299</id><published>2008-02-29T08:59:00.000-08:00</published><updated>2008-02-29T08:59:00.000-08:00</updated><title type='text'>Thanks for the feedback, everybody! A couple of th...</title><content type='html'>Thanks for the feedback, everybody! A couple of thoughts.&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Jorge:&lt;/B&gt; I'm not saying Ruby should disallow changing object types at runtime or that it should disallow having completely untyped variables. But when I know I need a particular interface (not a class), why can't I tell the compiler so it can enforce it? Isn't it the job of compilers to take work off of programmers?&lt;BR/&gt;&lt;BR/&gt;And as for those strings read in from the command line that get evaled? Great idea for a dev tool. Bad idea for a server. Ever hear of "SQL Injection"?&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Tante:&lt;/B&gt; Here's a challenge. Write your version of render(obj) that doesn't use respond_to and has the same functionality: 1. If the object can convert itself to HTML use that; 2. If the object can can convert itself to JSON, use that; 3. Otherwise, generate HTML from the object using to_s; 4. Don't hide any errors by masking exceptions other than those necessary to determine 1 &amp; 2. Bonus points if you make it easy to add extra cases in the future, like generating HTML from XML that the object provides.&lt;BR/&gt;&lt;BR/&gt;My version of this is pretty ugly. If you write a good example, I'll add it to the post.&lt;BR/&gt;&lt;BR/&gt;&lt;B&gt;Dave:&lt;/B&gt; You're right. I didn't mean to imply that you supported using respond_to? regularly. Sorry. That section does have one of my favorite footnotes. I also use respond_to? rarely, but I would like not to use it at all because every time I do use it, the compiler could have done it for me.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/6563220170331002299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/6563220170331002299'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204304340000#c6563220170331002299' title=''/><author><name>Roy Leban</name><uri>http://www.blogger.com/profile/08749140682886637193</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-225288892'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-6052295652812599150</id><published>2008-02-29T07:03:00.000-08:00</published><updated>2008-02-29T07:03:00.000-08:00</updated><title type='text'>To be fair, I don't really advocate respond_to in ...</title><content type='html'>To be fair, I don't really advocate respond_to in the book: I just say that it's available, and show how you could use it. At the end of the section, I say "However, before going down this path, make sure you're getting&lt;BR/&gt;a real benefit---it's a lot of extra code to write and to maintain."&lt;BR/&gt;&lt;BR/&gt;I personally use respond_to very rarely.&lt;BR/&gt;&lt;BR/&gt;&lt;BR/&gt;Dave</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/6052295652812599150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/6052295652812599150'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204297380000#c6052295652812599150' title=''/><author><name>pragdave</name><uri>http://www.blogger.com/profile/09135884431118390582</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-274946338'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-2306498952862957792</id><published>2008-02-29T04:21:00.000-08:00</published><updated>2008-02-29T04:21:00.000-08:00</updated><title type='text'>I personally come from a Python background but I g...</title><content type='html'>I personally come from a Python background but I guess it's somewhat similar so I'll respond here.&lt;BR/&gt;&lt;BR/&gt;If I'm not mistaken, respond_to? is the check whether a certain object has a certain method/attribute.&lt;BR/&gt;&lt;BR/&gt;Using that is just not very good style from a duck typing background. There's the saying "It's easier to ask for forgiveness than for permission" and it applies here:&lt;BR/&gt;&lt;BR/&gt;You don't check first and call then, that leads to ugly code.&lt;BR/&gt;&lt;BR/&gt;if you have an instance i with three serializers "to_html", "to_json" and "to_xml" for example, you'd just call the serializer you need at that moment:&lt;BR/&gt;If you need json, call the appropriate serializer, if there is an issue, you get the exception that tells you what is wrong. If you want things like a hierarchy of serializers as "If json doesn't work, gimme XML and if that fails gimme the string", wrap that in a function and just call that.&lt;BR/&gt;&lt;BR/&gt;The idea of the necessity of checking before calling comes usually from people that have a strong Java/C# background, because they feel they have to do manually what in Java/C+ the compiler does. But that is not how you program dynamic languages, that is trying to make them Java. Which they ain't.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2306498952862957792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/2306498952862957792'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204287660000#c2306498952862957792' title=''/><author><name>tante</name><uri>http://www.blogger.com/profile/13712377319723399136</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://www.the-gay-bar.com/images/PirateMonkey.jpg'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-782692888'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-3570372416330462400</id><published>2008-02-29T03:35:00.000-08:00</published><updated>2008-02-29T03:35:00.000-08:00</updated><title type='text'>You say:&lt;br&gt;&lt;br&gt;"And what if the compiler could ch...</title><content type='html'>You say:&lt;BR/&gt;&lt;BR/&gt;"And what if the compiler could check variables passed to methods to see if they support the requested interfaces and give you compile-time errors instead of runtime errors? ... None of this is fundamentally incompatible with Ruby."&lt;BR/&gt;&lt;BR/&gt;Compile-time type-checking is indeed fundamentally incompatible with Ruby, because Ruby allows you to change the type of an object at run-time. With Ruby, you can't know the run-time type of an object at compile-time.&lt;BR/&gt;&lt;BR/&gt;Consider code like:&lt;BR/&gt;&lt;BR/&gt;def myMethod(MyInterface i)&lt;BR/&gt;  ...&lt;BR/&gt;end&lt;BR/&gt;&lt;BR/&gt;obj = eval "MyClass.new"&lt;BR/&gt;&lt;BR/&gt;myMethod(obj)&lt;BR/&gt;&lt;BR/&gt;We know that the type of "obj" is "MyClass", so we can determine whether or not MyClass implements MyInterface. But what if the string passed to "eval" is read in from the command-line or from a file? How would you determine the type of obj at compile-time?</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3570372416330462400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/3570372416330462400'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204284900000#c3570372416330462400' title=''/><author><name>Jorge Ortiz</name><uri>http://www.blogger.com/profile/14454965475839432618</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1962474094'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-4230700666566360262</id><published>2008-02-29T00:41:00.000-08:00</published><updated>2008-02-29T00:41:00.000-08:00</updated><title type='text'>Clearly, I didn't provide the best example. I was ...</title><content type='html'>Clearly, I didn't provide the best example. I was trying to keep it short and I threw in the exception as the third option to show how that shouldn't be necessary with optional typing. I've updated the post with a better example.&lt;BR/&gt;&lt;BR/&gt;The point isn't about respond_to? &lt;I&gt;(A purist could even argue that respond_to? shouldn't exist -- we should just try the method in question and rescue if it throws an exception)&lt;/I&gt;.&lt;BR/&gt;&lt;BR/&gt;The problem is the inability to specify requirements for variables and parameters when they are known. People use respond_to? to work around this deficiency.&lt;BR/&gt;&lt;BR/&gt;I don't want my code throwing exceptions at runtime, especially on a server. I don't want the "or it doesn't" half of the "if it quacks" statement. I want the language, the system, and the compiler to make me more efficient and to help me avoid stupid mistakes.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/4230700666566360262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/4230700666566360262'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204274460000#c4230700666566360262' title=''/><author><name>Roy Leban</name><uri>http://www.blogger.com/profile/08749140682886637193</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-225288892'/></entry><entry><id>tag:blogger.com,1999:blog-8840979806248747743.post-985316608660162484</id><published>2008-02-29T00:11:00.000-08:00</published><updated>2008-02-29T00:11:00.000-08:00</updated><title type='text'>I agree that this use of respond_to? is horrible, ...</title><content type='html'>I agree that this use of respond_to? is horrible, but this is not a good demonstration of duck typing. It's not duck typing if you have to check to make sure it quacks. It should either quack or it shouldn't. If it quacks, then it works. If it doesn't quack, it should throw its own exception. That is, you shouldn't have to throw your own if it doesn't quack. That's done for you already. Also, this whole deal where you try a different method if the first doesn't work… that seems to be some tight coupling, which is kind of making it miss the whole point.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/985316608660162484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8840979806248747743/3020389393451158861/comments/default/985316608660162484'/><link rel='alternate' type='text/html' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html?showComment=1204272660000#c985316608660162484' title=''/><author><name>geezusfreeek2</name><uri>http://openid.aol.com/geezusfreeek2</uri><email>noreply@blogger.com</email><gd:image xmlns:gd='http://schemas.google.com/g/2005' rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/openid16-rounded.gif'/></author><thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' href='http://www.thisdev.com/2008/02/myth-of-duck-typing.html' ref='tag:blogger.com,1999:blog-8840979806248747743.post-3020389393451158861' source='http://www.blogger.com/feeds/8840979806248747743/posts/default/3020389393451158861' type='text/html'/><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='blogger.itemClass' value='pid-1112062127'/></entry></feed>
