<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Talk Like A Duck: Tag ruby</title>
    <link>http://talklikeaduck.denhaven2.com/articles/tag/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In Ruby, it's not the dog, it's the tricks!</description>
    <item>
      <title>Speaking Tomorrow at Raleigh Ruby Brigade</title>
      <description>&lt;p&gt;I&amp;#8217;ll be giving a talk on &amp;#8220;The Fall and Rise of Dynamic Languages&amp;#8221; 
&lt;a href="http://ruby.meetup.com/3/calendar/7849490/?a=nr1p_grp"&gt;tomorrow at 7:00 p.m., at Red Hat HQ to the Raleigh Ruby Brigade.&lt;/a&gt;
&lt;p&gt;Originally this was going to be a slightly revamped talk I gave some months ago to the local Agile group, with a slight change of emphasis from the history of agile methods to focus more on Ruby and other dynamic languages.  It&amp;#8217;s morphed into a  completely different talk.&lt;/p&gt;
&lt;p&gt;I plan to take a journey from the 1970s to today, and compare and contrast static and dynamic languages, and examine the recent resurgence in interest in dynamic languages and virtual machines.  Along the way, I&amp;#8217;ll have a few things to say about whether or not the recent news from RailsConf about MagLev is hype or reality.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re in the area, please come by.  Luckily the salmonella scare will probably keep the supply of (rotten) tomatoes to a minimum, so I should be fairly safe.&lt;/p&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 16 Jun 2008 15:16:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:da0fd57b-ad59-4688-921d-cbe802890a48</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2008/06/16/speaking-tomorrow-at-raleigh-ruby-brigade</link>
      <category>site_news</category>
      <category>ruby</category>
      <category>smalltalk</category>
      <category>javascript</category>
      <category>talks</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/503</trackback:ping>
    </item>
    <item>
      <title>Big Dave on Video</title>
      <description>InfoQ recently published a &lt;a href="http://www.infoq.com/interviews/dave-thomas-programming-languages-soa-and-the-web"&gt;video interview with Dave Thomas (of &lt;span class="caps"&gt;OTI&lt;/span&gt; fame)&lt;/a&gt;.
&lt;p&gt;In his inimitable style, Dave covers lots of interesting topics in software development, both today and with a historical perspective.&lt;/p&gt;
&lt;p&gt;I agree with almost everything he says, and find the rest food for thought.&lt;/p&gt;
&lt;p&gt;His comments about Java as a platform are quite germane to the article I published yesterday.  If you&amp;#8217;ve been exposed to Big Dave before, you&amp;#8217;ll enjoy this, and if you haven&amp;#8217;t it&amp;#8217;s a good introduction.&lt;/p&gt;</description>
      <pubDate>Tue, 29 Apr 2008 22:24:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:57c38e47-d746-4687-9434-480b47fdcab7</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2008/04/29/big-dave-on-video</link>
      <category>BigDave</category>
      <category>java</category>
      <category>smalltalk</category>
      <category>ruby</category>
      <category>iconoclasts</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/497</trackback:ping>
    </item>
    <item>
      <title>Aspects of Beauty: Proportion, Integrity, Clarity, and Monkey Patching?</title>
      <description>&lt;p&gt;&lt;img src="http://talklikeaduck.denhaven2.com/files/beauty_small.png" class="tease-image"/&gt;
Besides being a master werewolf, Marcel Molina Jr. gives great presentations!
&lt;p&gt;
In his keynote presentation on the second day of the Ruby Hoedown, Marcel talked about 
&lt;a href="http://rubyhoedown2007.confreaks.com/session09.html"&gt;&amp;#8220;What Makes Code Beautiful&amp;#8221;&lt;/a&gt;,
click on the link for the confreaks video of this session.
&lt;/p&gt;
&lt;p&gt;
The talk started with an exploration of the classical Philosophy of Beauty, from Plato to Descartes.
Marcel summarized this by proposing that beauty lies in the balance between three aspects which, 
at times, either strengthen or oppose each other:&lt;/p&gt;&lt;/p&gt;


&lt;dl&gt;
&lt;dt&gt;Proportion&lt;/dt&gt;&lt;dd&gt;The property that components have the appropriate(relative) size/weight.&lt;/dd&gt;
&lt;dt&gt;Integrity&lt;/dt&gt;&lt;dd&gt;I would summarize this as &amp;#8220;fitness of purpose.&amp;#8221;  Marcel&amp;#8217;s anti-example was a
hammer made out of glass. Although it might be beautifully constructed, and a joy to the eye, it
would be unlikely to serve its intended purpose, and thus would fall short on integrity&lt;/dd&gt;
&lt;dt&gt;Clarity&lt;/dt&gt;The property of being easily grasped as to meaning and function.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2&gt;Beauty and Ruby&lt;/h2&gt;
&lt;p&gt;About 16 minutes into the talk, Marcel started talking about this view of beauty in the context of Ruby code.  He gave an example of some really &amp;#8220;clever&amp;#8221; code to convert strings to an appropriate
instance of a Ruby class, for example &amp;#8220;true&amp;#8221; would me converted to true, &amp;#8220;false&amp;#8221; to false, and 
strings representing integer or time values to Integers or Times, respectively.&lt;/p&gt;
&lt;p&gt;The code in question, implemented a kind of functional language pattern match against the string.
Marcel suggested that he might have been into studying Haskell at the time he wrote this code.
He used a generator to produce an enumerable collection of patterns to try, and did some &amp;#8220;nice&amp;#8221; 
tricks to allow the result of a pattern match to sometimes be solely the value he wanted, and 
sometimes to be an array with the value as the second element, to handle the special case where the 
desired value was the literal false.  If it sounds complicated, it is, I&amp;#8217;ve placed the code at
the end of this article.  
Some of us in the audience, &amp;#8220;smelled&amp;#8221; this code right away.&lt;/p&gt;
&lt;p&gt;He then critiqued this solution. Although he had originally considered it &amp;#8220;beautiful&amp;#8221; since it was &amp;#8220;elegant&amp;#8221; and &amp;#8220;sophisticated&amp;#8221; he came to smell it too.&lt;/p&gt;
&lt;h2&gt;A Fresh Design&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s how the code ultimately was written:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CoercibleString&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;coerce&lt;/span&gt;
    &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;          &lt;span class="constant"&gt;true&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;         &lt;span class="constant"&gt;false&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;^&lt;span class="escape"&gt;\d&lt;/span&gt;+$&lt;/span&gt;&lt;span class="punct"&gt;/:&lt;/span&gt;         &lt;span class="constant"&gt;Integer&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="ident"&gt;datetime_format&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="constant"&gt;self&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once this much simpler design is unveiled the original &amp;#8220;sophisticated&amp;#8221;, and &amp;#8220;elegant&amp;#8221; design
looks anything but.&lt;/p&gt;
&lt;h2&gt;Measuring against Proportion, Integrity, and Clarity&lt;/h2&gt;
&lt;dl&gt;
&lt;dt&gt;Proportion&lt;/dt&gt;&lt;dd&gt;The original is a total failure, it&amp;#8217;s much too long compared to the final
code.&lt;/dt&gt;
&lt;dt&gt;Integrity&lt;/dt&gt;&lt;dd&gt;Again the original loses on this aspect. The use of the generator, particularly
the early continuation based implementation, causes very slow performance, and leaks memory. Marcel
stated that the simpler version is an order of magnitude faster.&lt;/dt&gt;
&lt;dt&gt;Clarity&lt;/dt&gt;&lt;dd&gt;Do I really have to explore this?&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Marcel had pointed out when describing the original design that one of it&amp;#8217;s &amp;#8220;cool features&amp;#8221; was
extensibility. Adding a new coercion just required adding another call to try in the Generator.new
block.&lt;/p&gt;
&lt;p&gt;In contrast adding a new coercion to the better design just requires adding a when leg to the
case statement.&lt;/p&gt;
&lt;h2&gt;The Questionable Beauty of Making Subclasses of Core Classes&lt;/h2&gt;
&lt;p&gt;While I loved the talk and agree with 99 and 44/100%,  I&amp;#8217;m just a bit troubled by the introduction
of the CoercibleString class.  I think that it falls down on proportion at least.&lt;p&gt;
&lt;p&gt;It seems to me that there&amp;#8217;s some missing code here.  How do you actually coerce a string.
This seems to strongly imply a usage like this:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PayloadProcessor&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;process&lt;/span&gt;
    &lt;span class="comment"&gt;# code which extracts a string to be coerced&lt;/span&gt;

    &lt;span class="comment"&gt;#coerce the string referenced by the variable value_str&lt;/span&gt;
    &lt;span class="ident"&gt;value&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;CoercibleString&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value_str&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;coerce&lt;/span&gt;

    &lt;span class="comment"&gt;#further processing&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An alternative, and it seems to me to be a better one, although I&amp;#8217;m convinceable otherwise, would
be to just make that method part of the class requiring the conversion, either directly, or through a
module:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;class PayloadProcessor

  def process
    # code which extracts a string to be coerced

    #coerce the string referenced by the variable value_str
    value = coerce(value_str)

    #further processing
  end

  def coerce(str)
    case str
    when 'true':          true
    when 'false':         false
    when /^\d+$/:         Integer(str)
    when datetime_format: Time.parse(str)
    else
      str
    end
  end

end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now some might argue that the &amp;#8216;functional&amp;#8217; looking coerce method which takes the string
as an argument rather than the receiver seems somehow less &amp;#8216;object oriented&amp;#8217;, but I find this
unconvincing.&lt;/p&gt;
&lt;p&gt;If CoercibleString is a class we need code to create it from a string, something like:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CoercibleString&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;
    &lt;span class="comment"&gt;# Create a new coercible string&lt;/span&gt;
    &lt;span class="comment"&gt;# Note that since the actual value of&lt;/span&gt;
    &lt;span class="comment"&gt;# Ruby strings are not held by an instance variable&lt;/span&gt;
    &lt;span class="comment"&gt;# we need to alter the internal representation&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;source_str&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="constant"&gt;self&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;source_str&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I had a brief conversation with Marcel about whether or not subclassing string really seemed
appropriate, but it lasted all of about a minute. There&amp;#8217;s a bit of supposition here on my
part, so apologies to Marcel if I misunderstood the exchange. He indicated that he would probably 
advocate
defining a method called CoercibleString, in parallel with Kernel#Integer and its ilk.&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Kernel&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;CoercibleString&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;str&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
     &lt;span class="constant"&gt;CoercibleString&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;str&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But this syntactic sugar, just seems to be tilting the balance towards a less proportional design.
&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Building new classes is often a good idea, but not always.  I&amp;#8217;m not totally convinced that
coerce(str) is more beautiful than CoercibleString.new(str).coerce, or CoercibleString(str).coerce,
but &lt;strong&gt;my&lt;/strong&gt; sense of esthetics tilts me that way.&lt;/p&gt;
&lt;p&gt;Comments?&lt;/p&gt;
&lt;h2&gt;A &amp;#8220;Smelly&amp;#8221; Way to Coerce Strings&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s Marcel&amp;#8217;s original code:&lt;/p&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CoercibleString&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;
  &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="ident"&gt;generator&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;coerce&lt;/span&gt;
    &lt;span class="ident"&gt;attempt&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;
    &lt;span class="keyword"&gt;break&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="ident"&gt;attempt&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;coercions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt; &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="ident"&gt;coercions&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;next?&lt;/span&gt;
    &lt;span class="ident"&gt;attempt&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="ident"&gt;attempt&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;private&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;coercions&lt;/span&gt;
      &lt;span class="constant"&gt;Generator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;generator&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;try&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;             &lt;span class="punct"&gt;}&lt;/span&gt;
        &lt;span class="ident"&gt;try&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt; &lt;span class="punct"&gt;]&lt;/span&gt;  &lt;span class="punct"&gt;}&lt;/span&gt;
        &lt;span class="ident"&gt;try&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="constant"&gt;Integer&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;              &lt;span class="punct"&gt;}&lt;/span&gt;
        &lt;span class="ident"&gt;try&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="constant"&gt;Date&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;           &lt;span class="punct"&gt;}&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;try&lt;/span&gt;
        &lt;span class="ident"&gt;attempt&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;desired&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="keyword"&gt;yield&lt;/span&gt;
        &lt;span class="ident"&gt;generator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;yield&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;desired&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="ident"&gt;attempt&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="ident"&gt;desired&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;attempt&lt;/span&gt;
    &lt;span class="keyword"&gt;rescue&lt;/span&gt; &lt;span class="constant"&gt;ArgumentError&lt;/span&gt;
        &lt;span class="ident"&gt;generator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;yield&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Mon, 20 Aug 2007 14:25:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:736e1dfe-1fec-46d1-994d-15838271c4eb</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2007/08/20/aspects-of-beauty-proportion-integrity-clarity-and-monkey-patching</link>
      <category>ruby</category>
      <category>best_practices</category>
      <category>ruby</category>
      <category>rubyhoedown</category>
      <category>beautiful_code</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/456</trackback:ping>
    </item>
    <item>
      <title>Performance Anxiety</title>
      <description>&lt;p&gt;I've been meaning to write about Ruby performance for a while, and a recent blog post by an old friend and colleague, got me off my proverbial.&lt;/p&gt;

&lt;p&gt;The old friend is John Duimovich, who wrote about the relative performance of &lt;i&gt;C++&lt;/i&gt; and &lt;i&gt;Smalltalk&lt;/i&gt; and &lt;a href="http://duimovich.blogspot.com/2006/09/performance-is-not-optional.html"&gt;what that could mean for ruby.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;John's message is important for those who bemoan the performance of Ruby, and I plan to expand on that message in this and later posts to this blog, but first a few words about Mr. Duimovich.&lt;/p&gt;

&lt;h2&gt;Consider the source&lt;/h2&gt;
&lt;p&gt;In his day job, paraphrasing his self description John "works for IBM on &lt;i&gt;Java&lt;/i&gt; virtual machines and is the lead on the Eclipse tools project management commitee."&lt;/p&gt;

&lt;p&gt;But some of my readers might be interested in John's background.  John was for a very long time, the lead of the &lt;i&gt;Smalltalk&lt;/i&gt; and &lt;i&gt;Java&lt;/i&gt; virtual machine team at Object Technology International (OTI) dating from before the time it was acquired by IBM.  Among other things John was responsible for the development of embedded &lt;i&gt;Smalltalk&lt;/i&gt; virtual machines from OTI, which spawned the VM used in Smalltalk/V Mac, IBM Smalltalk (used in IBM/VisualAge), the 'Universal' Virtual machine which implemented Java on an extended Smalltalk VM, and which was used for the early releases of IBM/VisualAge for Java, and the J9 Java VM.  A good deal of what I know about implementing VMs comes from working, lunching, and bar-hopping with John.&lt;/p&gt;
&lt;p&gt;John had become OTI's Chief Technology Officer before OTI got assimilated into the IBMborg.&lt;/p&gt;

&lt;p&gt;John is a brilliant guy, with a great sense of humor. Two characteristics which seem to have been requirements for a job at OTI.  I'm still not sure how I ended up spending several years there.&lt;/p&gt;

&lt;h2&gt;Dynamically Typed Doesn't Need to Mean Slow&lt;/h2&gt;
&lt;p&gt;I encourage you to read John's blog post yourself, but to summarize; John ran across another blog item which gave a benchmark written in &lt;i&gt;C++&lt;/i&gt;, &lt;i&gt;Ruby&lt;/i&gt; and &lt;i&gt;Python&lt;/i&gt;. The &lt;i&gt;C++&lt;/i&gt; version runs in under 1/10 of the time needed for either the &lt;i&gt;Ruby&lt;/i&gt; or &lt;i&gt;Python&lt;/i&gt; versions.&lt;/p&gt;

&lt;p&gt;John duplicated the results on his machine, then decided to port the &lt;i&gt;Ruby&lt;/i&gt; version of the benchmark to &lt;i&gt;Smalltalk&lt;/i&gt;.  He then ran it using VisualAge Smalltalk.&lt;/p&gt;

&lt;p&gt;And the &lt;i&gt;Smalltalk&lt;/i&gt; version runs in the same time as the optimized C++ version!&lt;/p&gt;

&lt;p&gt;How can this be?&lt;/p&gt;

&lt;h2&gt;The Value of Pole Vaulting&lt;/h2&gt;
&lt;p&gt;Languages like &lt;i&gt;Smalltalk&lt;/i&gt; and &lt;i&gt;Self&lt;/i&gt; started from the position that a clean object-oriented language was more important than one which makes compromises to make efficient implementation obvious.&lt;/p&gt;

&lt;p&gt;Early implementations of &lt;i&gt;Smalltalk&lt;/i&gt; used obvious implementations of some features, which were 'fast enough' in many cases, but by no means fast.  Two areas which cried for improvement were method dispatch and garbage colection.  The obvious techniques were walking up the class hierarchy each time a method was needed, and relatively easy to implement GC techniques like reference counting, and mark-and-sweep.  Reference counting has a fairly high cost for each change of an object reference, and also has the drawback of leaking memory because cyclical references lead to garbage which is uncollectable.  Mark and sweep delays the overhead until storage is exhausted, but leads to more perceptible pauses when the application gets paused so that the housemaid cleans the room.&lt;/p&gt;

&lt;p&gt;Encountering (or having set) this high bar, various implementors of these languages found very clever techniques for both problems.  Dave Ungar made measurements of the lifespans of &lt;i&gt;Smalltalk&lt;/i&gt; objects and observed that most objects  died very shortly after being instantiated, with few living a long life.  This led to the invention of generational GC techniques, which quickly dispatched young dead objects, which are the vast majority.&lt;/p&gt;

&lt;p&gt;Method dispatching techniques of efficiently implemented dynamically typed languages tend to use clever caching algorithms which can get to what is probably the right method quickly, with a quick test to make sure that the right method was found.&lt;/p&gt;

&lt;p&gt;These dispatching techniques turn out to be faster than the virtual function pointer dispatching made possible by strongly-typed languages like &lt;i&gt;C++&lt;/i&gt;.  In fact, I've heard that more modern implementations of these languages have actually used a more dynamic method dispatch mechanism internally in order to &lt;b&gt;increase&lt;/b&gt; performance.&lt;/p&gt;

&lt;p&gt;Anoher implementation choice is how to represent executable code. Most efficient implementations use a combination of byte-code representation, and some form of just-in-time translation of byte-codes to machine code.  Just how to divide execution between byte-code and machine code is a complicated decision.  Back when DIgitalk first produced a version of Smalltalk/V for OS/2, they decided to eschew byte-codes entirely and generate 80286 machine code.  The reason was that they were tired of hearing complaints about &lt;i&gt;Smalltalk&lt;/i&gt; being an 'interpreted' language.&lt;/p&gt;

&lt;p&gt;The surprising result of this experiment was that the resulting implementation was slower.  Machine code was bigger, so it took longer to load, and caused more swapping.  These costs were paid whether the code in question was executed once or a million times.&lt;/p&gt;

&lt;p&gt;Again caching was the basis for getting the best of both worlds.  Peter Deutsch of Xerox, later ParcPlace, had introduced the notion of translating byte-codes to machine code into a cache during execution, David Ungar's implementation of &lt;i&gt;Self&lt;/i&gt; introduced the notion of using light-weight profiling techniques to avoid the overhhead of translating byte-coded methods which were infrequently executed.&lt;/p&gt;

&lt;p&gt;Another area which posed difficulties in implementation was control flow.  Smalltalk-80 defines all control flow as methods. Even primitive control flow constructs such as if (&lt;b&gt;ifTrue:&lt;/b&gt; in &lt;i&gt;Smalltalk&lt;/i&gt;) were &lt;i&gt;implemented&lt;/i&gt; as methods on Boolean classes.  This is one area where &lt;i&gt;Smalltalk&lt;/i&gt; implementations &lt;i&gt;cheated&lt;/i&gt; compiling such methods in to testing and branching byte-codes, and requiring the receivers to be boolean instances.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Self&lt;/i&gt; eschewed this &lt;i&gt;early optimization&lt;/i&gt;.  Ungar's team instead relied on run-time type inference in order to dynamicaly generate code which achieved the same or better performance when such a message was sent to a boolean without restricting other cases.&lt;/p&gt;

&lt;h2&gt;The Current State of Ruby Implementation&lt;/h2&gt;
&lt;p&gt;&lt;i&gt;Ruby&lt;/i&gt; performance today is surprisingly &lt;i&gt;acceptable&lt;/i&gt; for a wide range of uses.&lt;/p&gt;

&lt;p&gt;This is despite the fact that the implementation is relatively straightforward, almost to the point of being naive. In the current standard implementation of Ruby:
&lt;ul&gt;
&lt;li&gt;Method dispatch is done by walking up the 'class' hierarchy looking for methods in a hash table in each class/module.&lt;/li&gt;
&lt;li&gt;Garbage Collection is done by a simple mark and sweep algorithm.&lt;/li&gt;
&lt;li&gt;Executable code is represented by a parse tree which is executed by traversal.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;This is not meant to understate the achievements of Matz and the ruby developers. &lt;i&gt;Ruby&lt;/i&gt; as it is definitely usable for many production uses.&lt;/p&gt;

&lt;p&gt;The point is how much better &lt;i&gt;Ruby&lt;/i&gt; performance can get as the implementation matures.  A virtual machine, with byte-codes, and better GC is on the roadmap.  &lt;i&gt;Ruby&lt;/i&gt; virtual machines such as YARV, and JRuby are showing glimmers of the value of implementing &lt;i&gt;Ruby&lt;/i&gt; as a virtual machine.  If &lt;i&gt;Ruby&lt;/i&gt; continues to grow in acceptance, I've no doubt that other clever implementers with experience in efficently implementing dynamically typed languages will provide more implementations.&lt;/p&gt;

&lt;p&gt;My prediction is that the future will be so bright that we're going to have to wear (ruby colored) shades!&lt;/p&gt;</description>
      <pubDate>Tue, 26 Sep 2006 15:17:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:6db85990-2780-4ce7-91fd-b122e3398ce5</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2006/09/26/performance-anxiety</link>
      <category>ruby</category>
      <category>smalltalk</category>
      <category>smalltalk</category>
      <category>ruby</category>
      <category>self</category>
      <category>performance</category>
      <category>implementation</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/39</trackback:ping>
    </item>
    <item>
      <title>Ducks Can Be Subtle Birds</title>
      <description>&lt;p&gt;One theory I&amp;#8217;ve seen defines a &amp;#8220;duck type&amp;#8221; as a set of messages which an object bound to a parameter or value needs to understand.  This leads some, who want to make type-checking happen a bit earler, to propose testing the values of such variables with oneor more respond_to? tests before using the object &amp;#8220;in anger.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;But ducks can be subtle&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Sometimes it&amp;#8217;s not enough just to have a certain set of methods in a duck&amp;#8217;s repetoire.&lt;/p&gt;


Let&amp;#8217;s look at an, admittedly cooked-up, example:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;dictionary&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
     &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;dictionary&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;collect&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt; &lt;span class="punct"&gt;}).&lt;/span&gt;&lt;span class="ident"&gt;compact&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
The method is intended to return an array containing
keys in a &amp;#8220;Dictionary&amp;#8221; which map to the given value:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;irb(main):001:0&amp;gt; load 'reverse_lookup.rb'
=&amp;gt; true

irb(main):002:0&amp;gt; reverse_lookup(1, { 'a' =&amp;gt; 1, 'b' =&amp;gt; 2, 'c' =&amp;gt; 1})
=&amp;gt; [&amp;quot;a&amp;quot;, &amp;quot;c&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Now, I said that this was a &amp;#8220;cooked-up&amp;#8221; example to illustrate a point about &amp;#8220;ducks.&amp;#8221; It would probably be more proper to implement a method like keys_for_value in Hash or a module which could be used to extend Hash or other &amp;#8220;dictionary&amp;#8221; classes.

	&lt;p&gt;The point here is that for this implementation of reverse_lookup, the only message sent to dictionary is collect, soaccording to the &amp;#8220;respond_to?&amp;#8221; theory any object which has &amp;#8220;collect&amp;#8221; in it&amp;#8217;s repetoire is the right species of duck for the dictionary parameter.&lt;/p&gt;


So let&amp;#8217;s try another duck:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;irb&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;main&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;&lt;span class="number"&gt;003&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Well, it works in the sense that nothing blows up, but the results look strange, where did that 0 come from?&lt;/p&gt;


While you weren&amp;#8217;t looking, I snuck a debug parameter into my reverse_lookup method to give an &amp;#8220;x-ray&amp;#8221; view into what&amp;#8217;s happening.
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;irb&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;main&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;&lt;span class="number"&gt;004&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;kv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="ident"&gt;kv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;
&lt;span class="ident"&gt;kv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;kv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]=&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
The reason that it works at all with an array of integers is a bit of an anomally due to the fact that Ruby integers define the [] method as a bit reference. When kv is an integer kv&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; and kv&lt;sup&gt;&lt;a href="#fn0"&gt;0&lt;/a&gt;&lt;/sup&gt; are respectively the least significant, and second least significant bits in the binary representation of kv.

	&lt;p&gt;Now let&amp;#8217;s try another array;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;irb&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;main&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;&lt;span class="number"&gt;005&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="constant"&gt;Array&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;NilClass&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="constant"&gt;NoMethodError&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="ident"&gt;undefined&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt; `&lt;span class="punct"&gt;[]'&lt;/span&gt;&lt;span class="string"&gt; for NilClass:Class
        from ./reverse_lookup.rb:2:in `reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
        &lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="punct"&gt;./&lt;/span&gt;&lt;span class="ident"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rb&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="symbol"&gt;:in&lt;/span&gt; `&lt;span class="ident"&gt;reverse_lookup&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;
        from (irb):4
        from :0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
So this doesn&amp;#8217;t work at all.

	&lt;p&gt;To sum this up, &amp;#8220;duck types&amp;#8221; aren&amp;#8217;t just collections of messages, whether or not an object will work in any given role also depends on subtleties of the semantics of theimplementation of the corresponding methods, and can also depend on the state of the object as well.&lt;/p&gt;


	&lt;p&gt;Now this shouldn&amp;#8217;t be considered a weakness of &amp;#8220;duck typing&amp;#8221; compared to &amp;#8220;strong typing,&amp;#8221; or something in-between the two. Strong-typing systems have similar &amp;#8220;flaws&amp;#8221;  for example strongly typing a variable to an integer won&amp;#8217;t protect against division by zerowhcn the variable is used as a divisor, nor will it alone protect against out of bounds errors when it&amp;#8217;s used as an array index.  The errors which aren&amp;#8217;t detected by strong-typing is a much larger set than those which are.  In languages which provide limited run-time checking of code which has passed the strong-typing &amp;#8220;hurdle&amp;#8221; the effects can be disastrous. In my humble opinion, the benefits of dynamic typing far outweigh &amp;#8220;unlearning&amp;#8221; what has been taught by other languages such as C++ and Java.&lt;/p&gt;


	&lt;p&gt;Bjarne Stroustrup used to quip, in panel discussions over strong vs. dynamic typing (i.e C++ vs. Smalltalk), that he&amp;#8217;d hate to be a passenger on a plane which flashed a light labled &amp;#8220;message not understood&amp;#8221; in the cockpit when the pilot tried to lower the landing gear.  I&amp;#8217;d hate even more to be a passenger on a plane whose control software seg-faulted under this condition instead because putting the landing gear down caused a buffer overflow.&lt;/p&gt;


	&lt;p&gt;The real answer to uncovering and routing out errors is testing, testing, and more testing.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Aug 2006 11:09:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:57838eb5-1cde-4cad-8ad9-8aecb88af12c</guid>
      <author>Rick DeNatale</author>
      <link>http://talklikeaduck.denhaven2.com/articles/2006/08/10/ducks-can-be-subtle-birds</link>
      <category>ruby</category>
      <category>ducks</category>
      <category>types</category>
      <category>ruby</category>
      <trackback:ping>http://talklikeaduck.denhaven2.com/articles/trackback/7</trackback:ping>
    </item>
  </channel>
</rss>
