<?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 Module#method_added</title>
    <link>http://www.jvoorhis.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>jvoorhis comments</description>
    <item>
      <title>"Module#method_added": comment by JV</title>
      <description>&lt;p&gt;I read up on &lt;code&gt;overload.rb&lt;/code&gt; and it is very similar. Also worth checking out is Topher Cyll&amp;#8217;s &lt;a href="http://multi.rubyforge.org/"&gt;multi&lt;/a&gt; gem. His article titled, &lt;a href="http://www.artima.com/rubycs/articles/patterns_sexp_dslsP.html"&gt;If It&amp;#8217;s Not Nailed Down, Steal It&lt;/a&gt; is also a good read on the topic.&lt;/p&gt;


	&lt;p&gt;Also, you are right &amp;#8211; I don&amp;#8217;t believe the grammar for any existing implementation of Ruby could accomodate the traditional syntax for typing formal arguments. What makes these posts fun, however, is that we  can easily use pure Ruby to implement the semantics, even though the syntax isn&amp;#8217;t quite the same.&lt;/p&gt;</description>
      <pubDate>Wed, 11 Apr 2007 03:39:00 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-483</guid>
      <link>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-483</link>
    </item>
    <item>
      <title>"Module#method_added": comment by Daniel Berger</title>
      <description>&lt;p&gt;Actually, that&amp;#8217;s basically what overload.rb (and is similar to  Ryan Pavlik&amp;#8217;s strongtyping package).&lt;/p&gt;


I was hoping for this syntax:
&lt;pre&gt;
def hello
   "hello somebody" 
end

def hello(String name)
   "hello #{name}" 
end

def hello(Fixnum num)
   "hello number #{num}" 
end
&lt;/pre&gt;
Alas, I don&amp;#8217;t think it&amp;#8217;s possible without yacc hacking.</description>
      <pubDate>Wed, 11 Apr 2007 02:40:56 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-482</guid>
      <link>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-482</link>
    </item>
    <item>
      <title>"Module#method_added": comment by JV</title>
      <description>&lt;p&gt;Multiple dispatch based on type could be implemented easily using the same pattern. One possible solution is to accept a type signature before a method&amp;#8217;s implementation, like so:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class Recognizer
  extend Multi::Type
  multi do
    deftype /[[:alpha:]][_[:alnum]]*/
    def recognize(token)
      puts "Found an identifier!" 
    end

    deftype /\d+(\.\d+)?/
    def recognize(token)
      puts "Found a number!" 
    end

    deftype String
    def recognize(token)
      puts "Unknown token!" 
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The implementation would then dispatch to the first method whose formal arguments positionally match the message&amp;#8217;s actual arguments. Using the case comparison operator would allow us to mix and match classes, regular expressions, and so forth.&lt;/p&gt;</description>
      <pubDate>Tue, 10 Apr 2007 06:50:38 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-481</guid>
      <link>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-481</link>
    </item>
    <item>
      <title>"Module#method_added": comment by Daniel Berger</title>
      <description>&lt;p&gt;Yep, cool stuff. I think this is basically what overload.rb does (or something like it).&lt;/p&gt;


	&lt;p&gt;Now, if you can get it to accept a type to simulate overloaded methods via static typing, I&amp;#8217;ll be even more impressed. :)&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m also curious how the various &lt;span class="caps"&gt;IDE&lt;/span&gt;&amp;#8217;s out there would handle such code.&lt;/p&gt;


	&lt;p&gt;Dan&lt;/p&gt;</description>
      <pubDate>Tue, 10 Apr 2007 06:18:40 NZST</pubDate>
      <guid>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-480</guid>
      <link>http://www.jvoorhis.com/articles/2007/04/09/module-method_added#comment-480</link>
    </item>
    <item>
      <title>"Module#method_added" by jvoorhis</title>
      <description>&lt;p&gt;Two days ago, I discovered &lt;code&gt;Module#method_added&lt;/code&gt; lurking about in the &lt;a href="http://drp.rubyforge.org/"&gt;DRP&lt;/a&gt; library. Today, let&amp;#8217;s take a look at what it does, along with an example implementation of multiple dispatch for Ruby objects.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;Module#method_added&lt;/code&gt; accepts one parameter &amp;#8211; a symbol allowing us to reference the method that was just defined in a class or module definition.  We may do a number of things with only that method name &amp;#8211; inspect the method, rename it, change its scope, or &amp;#8211; in our case &amp;#8211; register it with our multiple dispatch system.&lt;/p&gt;


	&lt;p&gt;The following code is both crude and simple: it allows us to define multimethods based on their arity, and does not support optional arguments or variable-length argument lists. It also only takes hold within the &lt;code&gt;multi do ... end&lt;/code&gt; block. With a little extra work, the &lt;code&gt;multi&lt;/code&gt; block could be eliminated, and missing features could be added. What is noteworthy is how reflective callbacks such as &lt;code&gt;Module#method_added&lt;/code&gt; and &lt;code&gt;Class#inherited&lt;/code&gt; make it possible to use the Ruby language to extend the Ruby language.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
module Multi
  module Arity
    def method_added(name)
      if @__multi_def__
        @__multi_def__ = false # Disable method_added behavior while aliasing
        arity = instance_method(name).arity
        @__multi_methods__ |= [name]
        class_eval "private :#{name}; alias __multi__#{name}__#{arity} #{name}" 
        @__multi_def__ = true
      end
    end

    def multi
      @__multi_methods__ = []
      @__multi_def__ = true
      yield
      @__multi_def__ = false

      @__multi_methods__.each do |name|
        define_method(name) { |*args| send("__multi__#{name}__#{args.size}", *args) }
      end
    end
  end
end

if __FILE__ == $0
  require 'test/unit'

  class Example
    extend Multi::Arity
    multi do
      def hello
        "Hello, somebody" 
      end

      def hello(name)
        "Hello, #{name}" 
      end
    end
  end

  class MultiTest &amp;lt; Test::Unit::TestCase
    def test_dispatch
      ex = Example.new
      assert_equal "Hello, somebody", ex.hello()
      assert_equal "Hello, multimethods", ex.hello("multimethods")
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

</description>
      <pubDate>Mon,  9 Apr 2007 10:16:00 NZST</pubDate>
      <guid>&lt;a href="/articles/2007/04/09/module-method_added"&gt;Module#method_added&lt;/a&gt;</guid>
      <link>&lt;a href="/articles/2007/04/09/module-method_added"&gt;Module#method_added&lt;/a&gt;</link>
    </item>
  </channel>
</rss>
