<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>jvoorhis comments on Specifying Duck Types in Ruby</title>
    <link>http://www.jvoorhis.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>jvoorhis comments</description>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by aMOMynous</title>
      <description>&lt;p&gt;And I thought ducktypes were mallard, teal, eider, merganser&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Wed,  9 May 2007 00:48:28 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-505</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-505</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by Thomas</title>
      <description>&lt;p&gt;Jeremy,&lt;/p&gt;


	&lt;p&gt;I think the concept of protocol Josh was referring to is outlined pretty decently &lt;a href="http://en.wikipedia.org/wiki/Protocol_%28object-oriented_programming%29"&gt;here&lt;/a&gt;. Though, I do seem to recall a variation on this that precedes &lt;span class="caps"&gt;OOP&lt;/span&gt;. I can see how your approach does bare a good resemblance to that definition.&lt;/p&gt;</description>
      <pubDate>Sat,  5 May 2007 10:23:08 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-504</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-504</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by Dan</title>
      <description>&lt;p&gt;I&amp;#8217;d love for something like this to be packaged up.  I&amp;#8217;d even go so far as to suggest bundling it up into an ActiveSupport module, and replacing all the when klass, kind_of? and is_a? type calls throughout the Rails source.&lt;/p&gt;</description>
      <pubDate>Sat,  5 May 2007 06:37:15 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-503</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-503</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by JV</title>
      <description>&lt;p&gt;That is incorrect, unless we are using wildly different versions of Ruby. Method objects obtained via Object#method, will retain their arity.&lt;/p&gt;


	&lt;p&gt;Your example ought to run just fine without displaying the aforementioned error on Ruby 1.8.x&lt;/p&gt;</description>
      <pubDate>Fri,  4 May 2007 17:15:18 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-502</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-502</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by Kenny Parnell</title>
      <description>&lt;p&gt;I just read what I wrote and realized that I wan&amp;#8217;t clear.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;JSON.method(:parse)&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;returns a method when that method is passed as a block to another method in a sense it is converted to the proc:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;Proc.new { JSON.parse(nil) }&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;which does not accept an argument when it is called and passes nil as &amp;#8216;data&amp;#8217;&lt;/p&gt;


	&lt;p&gt;on the other hand&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;lambda {|data| JSON.parse(data)}&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;does accept an argument.&lt;/p&gt;


	&lt;p&gt;P.S. &lt;code&gt;JSON.method(:parse).to_proc&lt;/code&gt; probably wouldn&amp;#8217;t work either for the same reason. :-) I wasn&amp;#8217;t thinking before.&lt;/p&gt;


	&lt;p&gt;For example&lt;/p&gt;


&lt;code&gt;
class MyClass
  def parse
    puts "hi from MyClass#parse" 
  end
end

pr = Proc.new { puts "hi from anonymous Proc" }
methproc = MyClass.new.method(:parse).to_proc

[1,2,3].each &amp;#38;pr         # "hi from anonymous Proc\n" * 3
[1,2,3].each &amp;#38;methproc   # in `talk': wrong # of arguments(1 for 0)
&lt;/code&gt;</description>
      <pubDate>Fri,  4 May 2007 16:30:21 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-501</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-501</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by JV</title>
      <description>&lt;p&gt;Methods do respond to call, and in many cases, can be treated like a closure object.&lt;/p&gt;


	&lt;p&gt;I did, however, forget about the Method#to_proc. Good call!&lt;/p&gt;</description>
      <pubDate>Fri,  4 May 2007 16:13:29 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-500</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-500</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by Kenny Parnell</title>
      <description>&lt;p&gt;Jeremy,&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;ActionController::Base.param_parsers[Mime::JSON] = JSON.method(:parse)&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;should not work the same as&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;ActionController::Base.param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;because &lt;code&gt;JSON.method(:parse)&lt;/code&gt; returns a method and methods do not respond to call.&lt;/p&gt;


	&lt;p&gt;You could have done&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;ActionController::Base.param_parsers[Mime::JSON] = JSON.method(:parse).to_proc&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;instead of woring about the &lt;code&gt;lambda...&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Fri,  4 May 2007 15:38:25 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-499</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-499</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by JV</title>
      <description>&lt;p&gt;Josh,&lt;/p&gt;


	&lt;p&gt;In what context is the term &amp;#8220;protocol&amp;#8221; equivalent? Could you point me to some background information?&lt;/p&gt;


	&lt;p&gt;Because &lt;em&gt;my&lt;/em&gt; duck types are ordinary Ruby code, a collection of duck types could be distributed as plain Ruby code, _require_d rather than registered.&lt;/p&gt;


	&lt;p&gt;The goal is to shift our reasoning about types in Ruby to emphasize capability rather than class. This is similar to interfaces in Java, except that an object may &lt;em&gt;satisfy&lt;/em&gt; a duck type with no knowledge of the type, as opposed to Java classes, where the object must derive from a class which explicitly implements the interface.&lt;/p&gt;


	&lt;p&gt;You can have a beer now.&lt;/p&gt;</description>
      <pubDate>Fri,  4 May 2007 13:06:29 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-498</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-498</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby": comment by josh</title>
      <description>&lt;p&gt;Nice. What you call duck types used to be called protocols way back when. This looks like a handy way to compare object behaviors.&lt;/p&gt;


	&lt;p&gt;It might be nice to have a place to put that Callable protocol so it can be shared among interested parties. Of course, that way lies the madness of type registries, but the other option is not very &lt;span class="caps"&gt;DRY&lt;/span&gt;. Then you have to contend with evolution of protocols over time and brittle types captured in the registry. Can I have a beer now?&lt;/p&gt;</description>
      <pubDate>Fri,  4 May 2007 12:49:51 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-497</guid>
      <link>http://www.jvoorhis.com/articles/2007/05/04/specifying-duck-types#comment-497</link>
    </item>
    <item>
      <title>"Specifying Duck Types in Ruby" by jvoorhis</title>
      <description>&lt;p&gt;While prototyping a &lt;span class="caps"&gt;RES&lt;/span&gt;Tful web service, I wrote the following code to allow Rails to parse a request&amp;#8217;s parameters from a &lt;span class="caps"&gt;POST&lt;/span&gt; request containing &lt;span class="caps"&gt;JSON&lt;/span&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
ActionController::Base.param_parsers[Mime::JSON] = JSON.method(:parse)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Unfortunately, it did not work, while the following code did:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
ActionController::Base.param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Theoretically, both of these should accomplish the same thing: assign an object that responds to the message &lt;code&gt;call&lt;/code&gt; with an arity of 1 to &lt;code&gt;Mime::JSON&lt;/code&gt; entry of the &lt;code&gt;param_parsers&lt;/code&gt; hash. They lead to different results, however, because a case statement within the Rails &lt;span class="caps"&gt;HTTP&lt;/span&gt; request parsing code watches for an instance of &lt;code&gt;Proc&lt;/code&gt;, instead of an object which responds to &lt;code&gt;call&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;As a proof of concept, I whipped up this &lt;code&gt;DuckType&lt;/code&gt; class:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class DuckType
  def initialize(*args)
    @args = args
  end

  def ===(other)
    @args.all? { |arg| other.respond_to?(arg) }
  end
end
&lt;/code&gt;&lt;/pre&gt;

Now, we can replace this statement from &lt;code&gt;cgi_methods.rb&lt;/code&gt;
&lt;pre&gt;&lt;code&gt;
case strategy = ActionController::Base.param_parsers[mime_type]
  when Proc
    strategy.call(raw_post_data)
  # snip...
end
&lt;/code&gt;&lt;/pre&gt;
with the following:
&lt;pre&gt;&lt;code&gt;
Callable = DuckType.new :call
case strategy = ActionController::Base.param_parsers[mime_type]
  when Callable
    strategy.call(raw_post_data)
  # snip...
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As you can see, an instance of &lt;code&gt;DuckType&lt;/code&gt; has a case comparison operator which asserts that all specified messages are supported, allowing you to focus on an object&amp;#8217;s capabilities rather than its class.&lt;/p&gt;


	&lt;p&gt;My &lt;code&gt;DuckType&lt;/code&gt; implementation in its current form is rather crude, but if enough people found this technique useful, I would consider properly packaging and extending it for general use.&lt;/p&gt;

</description>
      <pubDate>Fri,  4 May 2007 10:59:00 NZST</pubDate>
      <guid>&lt;a href="/articles/2007/05/04/specifying-duck-types"&gt;Specifying Duck Types in Ruby&lt;/a&gt;</guid>
      <link>&lt;a href="/articles/2007/05/04/specifying-duck-types"&gt;Specifying Duck Types in Ruby&lt;/a&gt;</link>
    </item>
  </channel>
</rss>
