<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rabbit Creative &#187; Object Thinking</title>
	<atom:link href="http://www.rabbitcreative.com/category/object-thinking/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rabbitcreative.com</link>
	<description>ruby, rails, objects and &#60;del&#62;politics&#60;/del&#62; markets</description>
	<lastBuildDate>Tue, 25 Oct 2011 02:14:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>The Greeks, the Object Thinkers and the Anarcho-capitalists.</title>
		<link>http://www.rabbitcreative.com/2011/02/03/the-greeks-the-object-thinkers-and-the-anarcho-capitalists/</link>
		<comments>http://www.rabbitcreative.com/2011/02/03/the-greeks-the-object-thinkers-and-the-anarcho-capitalists/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 06:27:32 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>
		<category><![CDATA[libertarian austro-libertarian anarcho-capitalist]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/?p=603</guid>
		<description><![CDATA[Excerpted from Object Thinking: In ancient Greece, an individual would act as his own agent in his own behalf, or combine with other people to act together as a team. In a Greek work environment, you bring your tools to work with you, you do your stuff, and then you pack up your tools and [...]]]></description>
			<content:encoded><![CDATA[<p>Excerpted from Object Thinking:</p>
<blockquote><p>In ancient Greece, an individual would act as his own agent in his own behalf, or combine with other people to act together as a team. In a Greek work environment, you bring your tools to work with you, you do your stuff, and then you pack up your tools and take them home. You are an individual—an independent contractor. You are not owned body and mind. You are merely providing a service for compensation.</p>
<p>In Rome, one’s first duty was to the group, clan, class, or faction upon which one depended for status. Known as gravitas, this meant sacrificing oneself for the good of the organization, and giving up one’s individuality and identifying closely with the group. In a Roman environment you go to work, the company hands you your tools, and then it holds you and your mind hostage until you sever your relationship with the organization. You are not an individual: you are owned by the organization body and mind, twenty-four hours a day. There are substantial rewards for this, however. The organization provides you with security, money, and power.</p></blockquote>
<p>Object Thinking is a book about programming. The dichotomy described above is strikingly similar to the literature describing the differences between collectivism and individualism. I sense a symmetry between the quantity of individuals who are true object-oriented programmers and the quantity of individuals who are truly libertarians.</p>
<p>The statist ideology runs deep. Divide and conquer. Adopt and attempt to override words and their definitions to suit a nefarious purpose. Programmers often think that because they&#8217;re employing the word &#8220;class&#8221; and &#8220;instance&#8221; that they are programming with objects. I find this similar to the confusion present in the minds of so many individuals regarding the nature of capitalism.</p>
<p>The top-down, command-and-control approach is disgusting, evil and inefficient. It is destined to fall. The lethargy and tragedy of collectivist thought pervades everything.</p>
<p>But I see you, collectivism. So long as there in breath in my lungs and blood in my veins, I will fight you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2011/02/03/the-greeks-the-object-thinkers-and-the-anarcho-capitalists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RSpec, meet Flow.</title>
		<link>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/</link>
		<comments>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/#comments</comments>
		<pubDate>Fri, 16 May 2008 00:20:12 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/</guid>
		<description><![CDATA[Flow is the demon that appears after about an hour of using RSpec. He sits on my shoulder and watches me code. After a few minutes he stands up. I know to turn down the music. He whispers into my ear. I nod in agreement and mouth back a response. Flow understands my frustration with [...]]]></description>
			<content:encoded><![CDATA[<p>Flow is the demon that appears after about an hour of using RSpec. He sits on my shoulder and watches me code.</p>
<p>After a few minutes he stands up. I know to turn down the music. He whispers into my ear. I nod in agreement and mouth back a response.</p>
<p>Flow understands my frustration with testing individual methods outside any greater context or usage scenario.</p>
<p>RSpec is a beautiful tool. Leaps and bounds ahead of the standard testing framework built into Rails. It does this, I believe, by allowing you to use more natural language. But it can be be misused. Which is actually closer to abuse, because unless you&#8217;re paying respect to flow, you&#8217;re fucking yourself.</p>
<p><strong>Don&#8217;t test methods outside of the context in which they should be used.</strong> It doesn&#8217;t mean shit to the person reading your code &#8212; even if that person is you.</p>
<p>Your program is a play. Your objects are actors. You are the writer and director. You say action! You say cut! You know all the lines, but it&#8217;s not your job to voice them. You assign those roles to your actors, and they carry it out much better than your sorry ass ever could.</p>
<p>Context. Acknowledge it. If your tests look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'An InterestList'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'upon creation'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'should not be a new record'</span>
    it <span style="color:#996600;">'should be empty'</span>
    it <span style="color:#996600;">'should report having zero Interest objects'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'when adding a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should answer true'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'with one ProductInventoryPrototype in it'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should not be empty'</span>
    it <span style="color:#996600;">'should report having one interest'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'removing a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should answer with the item when that item is removed'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'after removing a ProductInventoryPrototype'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">remove</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    it <span style="color:#996600;">'should be empty when that item is removed'</span>
    it <span style="color:#996600;">'should report having zero items'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You&#8217;re fucking with the laws of nature, and you will be smitten.</p>
<p>What&#8217;s wrong with it? The
<pre>#before</pre>
<p> code is reinitializing all the steps you&#8217;ve just accomplished.</p>
<p>Make it look like this.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
&nbsp;
      describe <span style="color:#996600;">'It now has one product in it.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
        before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        it <span style="color:#996600;">'It should not be empty.'</span>
        it <span style="color:#996600;">'It should report having one interest.'</span>
&nbsp;
        describe <span style="color:#996600;">'Now we remove a ProductInventoryPrototype.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
          it <span style="color:#996600;">'It should answer with the item when that item is removed.'</span>
&nbsp;
          describe <span style="color:#996600;">'After removing a ProductInventoryPrototype,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
            before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
              <span style="color:#0066ff; font-weight:bold;">@interest_list</span>.<span style="color:#9900CC;">remove</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cheese<span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
            it <span style="color:#996600;">'it should be empty when that item is removed.'</span>
            it <span style="color:#996600;">'it should report having zero items'</span>
&nbsp;
          <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Of primary importance is a subtle point. I didn&#8217;t illustrate it in the two examples above, but I will now:</p>
<p>Before:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
      it <span style="color:#996600;">'It should not be empty.'</span>
      it <span style="color:#996600;">'It should report having one interest.'</span>
...</pre></div></div>

<p>After:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe <span style="color:#996600;">'When working with an InterestList,'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@interest_list</span> = InterestList.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  describe <span style="color:#996600;">'it must first be created.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
    it <span style="color:#996600;">'It should not be a new record.'</span>
    it <span style="color:#996600;">'It should be empty.'</span>
    it <span style="color:#996600;">'It should report having zero Interest objects.'</span>
&nbsp;
    describe <span style="color:#996600;">' After which you can add a product.'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
      before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        <span style="color:#0066ff; font-weight:bold;">@cheese</span> = inventory_prototypes<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:cheese</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      it <span style="color:#996600;">'To which it should answer true.'</span>
&nbsp;
      describe <span style="color:#996600;">' At which point'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
        it <span style="color:#996600;">'it should not be empty.'</span>
        it <span style="color:#996600;">'it should report having one interest.'</span>
...</pre></div></div>

<p>On the surface it&#8217;s just another level of nesting. After meditation, you realize you are <em>first</em> testing the object&#8217;s answer to your message. <em>Second</em>, you are testing the state of the universe after that action is made. The difference is subtle, but important. If you don&#8217;t understand the importance, recall the indifference you felt when you first saw RSpec: <em>it&#8217;s Rails&#8217; standard test framework with different words thrown in.</em></p>
<p>You were wrong then and you&#8217;re wrong now.</p>
<blockquote><p>Words offer the means to meaning, and for those who will listen, the enunciation of truth. &#8211; V</p></blockquote>
<p>If an object&#8217;s answer to the message passed violates expectations, flow stops. You know, not that a <em>method</em> is broken, but that <em>flow</em> is broken.</p>
<p>Of secondary importance is that your
<pre>#before</pre>
<p> methods are no longer redundant.</p>
<p>The result of running your tests now looks like:</p>
<pre>
When working with an InterestList, it must first be created. It should not be a new record. (Not Yet Implemented)
When working with an InterestList, it must first be created. It should be empty. (Not Yet Implemented)
When working with an InterestList, it must first be created. It should report having zero Interest objects. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. To which it should answer true. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. It should not be empty. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. It should report having one interest. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. It should answer with the item when that item is removed. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. After removing a ProductInventoryPrototype, it should be empty when that item is removed. (Not Yet Implemented)
When working with an InterestList, it must first be created. After which you can add a product. It now has one product in it. Now we remove a ProductInventoryPrototype. After removing a ProductInventoryPrototype, it should report having zero items (Not Yet Implemented)
</pre>
<p>This is easier to read and understand than a series of isolated tests. You&#8217;re made aware of the context in which each test is being run, which is priceless when you&#8217;re attempting to understand the system from a high level.</p>
<p><strong>Congratulations.</strong> You are no longer a moron coding outside the realm of the context in which your code lives.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2008/05/15/rspec-meet-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I, Object.</title>
		<link>http://www.rabbitcreative.com/2008/03/17/i-object/</link>
		<comments>http://www.rabbitcreative.com/2008/03/17/i-object/#comments</comments>
		<pubDate>Mon, 17 Mar 2008 09:52:30 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/2008/03/17/i-object/</guid>
		<description><![CDATA[From the GNU Smalltalk documentation: I am an abstract class. My objects represent things that are discrete and map to a number line. My instances can be compared with < and >. The documentation is written from the perspective of the object. Brilliant.]]></description>
			<content:encoded><![CDATA[<p>From the <a href="http://www.gnu.org/software/smalltalk/manual-base/gst-base.html#Magnitude">GNU Smalltalk documentation</a>:</p>
<blockquote><p>I am an abstract class. My objects represent things that are discrete and map to a number line. My instances can be compared with < and >.</p></blockquote>
<p>The documentation is written from the perspective of the object. Brilliant.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2008/03/17/i-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Am I a bad programmer because I don&#8217;t like to write complicated code?</title>
		<link>http://www.rabbitcreative.com/2007/10/12/am-i-a-bad-programmer-because-i-dont-like-to-write-complicated-code/</link>
		<comments>http://www.rabbitcreative.com/2007/10/12/am-i-a-bad-programmer-because-i-dont-like-to-write-complicated-code/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 02:04:46 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/2007/10/12/am-i-a-bad-programmer-because-i-dont-like-to-write-complicated-code/</guid>
		<description><![CDATA[If a problem becomes more difficult than I feel it should be I decompose it. I take a step back, look at my surroundings and ask, &#8220;what am I trying to solve? Who are the characters in my story and what guides them to do the things they do?&#8221; It sounds epic, poetic and a [...]]]></description>
			<content:encoded><![CDATA[<p>If a problem becomes more difficult than I feel it should be I decompose it. I take a step back, look at my surroundings and ask, &#8220;what am I trying to solve? Who are the characters in my story and what guides them to do the things they do?&#8221;</p>
<p>It sounds epic, poetic and a little corny, but it&#8217;s how I think. And it&#8217;s how I program. I don&#8217;t like solving complicated tasks. I like breaking complicated tasks into many smaller, manageable tasks and solving those. Once each smaller task is solved, I script a dialog between them to achieve the desired effect.</p>
<p>Imagine a movie in which there was only one actor. That actor would have to play the good guy, the bad guy, the dame, all supporting characters and the director&#8217;s cameo. Such a movie would have to be classified as a psychological thriller, because it would take an insane person to be able to keep everything together. While the move may have been fun to make (for a sadist), few members of the audience would be able to follow the movie all the way through.</p>
<p>So as your audience leaves the theater, as your programmers leave your project, you realize that being clever and complicated may not have been the best choice.</p>
<p>No, I don&#8217;t think I&#8217;m a bad programmer. I think I&#8217;m a programmer with taste, my own style and a little class. Instead of banging the keys for eight hours, I spend an hour drawing with a pen and paper. Then I spent twenty minutes staring at the wall. I get up, walk around and stretch my legs. I take a piss. When I come back to the computer I have an intricate web of many, simple objects with obvious names and well-defined behaviors. At the end of the day I&#8217;m proud of the code I wrote.</p>
<p>And most importantly, I don&#8217;t dread coming back to it the next day.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2007/10/12/am-i-a-bad-programmer-because-i-dont-like-to-write-complicated-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Discovering self-evaluating objects. (pt. 2 of 2)</title>
		<link>http://www.rabbitcreative.com/2007/06/23/discovering-self-evaluating-objects-in-rails/</link>
		<comments>http://www.rabbitcreative.com/2007/06/23/discovering-self-evaluating-objects-in-rails/#comments</comments>
		<pubDate>Sat, 23 Jun 2007 21:53:47 +0000</pubDate>
		<dc:creator>Rabbit</dc:creator>
				<category><![CDATA[Object Thinking]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.rabbitcreative.com/2007/06/23/discovering-self-evaluating-objects-in-rails/</guid>
		<description><![CDATA[Notice: There&#8217;s quite a bit of code covered in this post. You can follow along with most of it using IRB. However, to run the final example, you&#8217;ll be better off downloading this complete Rails application. Follow the instructions in doc/readme. Notice: This is part two of a two-part post. Read the first post if [...]]]></description>
			<content:encoded><![CDATA[<p style="background: #FAFAD2; padding: 5px; border: 1px solid #CCCCCC; line-height: 1.5em;"><strong>Notice:</strong> There&#8217;s quite a bit of code covered in this post. You can follow along with most of it using IRB. However, to run the final example, you&#8217;ll be better off <a href='http://www.rabbitcreative.com/wp-content/uploads/2007/06/self-evaluating.zip' title='self-evaluating rails app'>downloading this complete Rails application</a>. Follow the instructions in doc/readme.</p>
<p style="background: #FAFAD2; padding: 5px; border: 1px solid #CCCCCC; line-height: 1.5em;"><strong>Notice:</strong> This is part two of a two-part post. <a href="http://www.rabbitcreative.com/2007/06/11/discovering-self-evaluating-objects-in-ruby/">Read the first post</a> if you haven&#8217;t already.</p>
<p>All right! We&#8217;re taking the experience we gained from our last endeavor, and we&#8217;re putting it on rails.</p>
<p>First off, let&#8217;s think about our goal &#8212; what are we trying to accomplish? How does it flow? What does it look like? In this case it&#8217;s pretty simple. It should probably look something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">product.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'cost'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>That&#8217;s concise, and it looks good. But it&#8217;s not the whole story. So let&#8217;s think some more.</p>
<p>We know we have products, as shown above. We have rules, presumably shown above as the argument to the evaluate method. What about variables? I don&#8217;t see those in the code above.</p>
<p>Before we go any further, let&#8217;s hash out a quick drawing to show our understanding of our objects and their relationships. &#8230; Done!</p>
<p><img src='http://www.rabbitcreative.com/wp-content/uploads/2007/06/diagram.gif' alt='diagram' /></p>
<p style="clear: both;">Pretty basic right now, but let&#8217;s talk about it.</p>
<p>Rules have many products have many variables. Interesting. When you say it like that, it almost doesn&#8217;t make sense. A rule has many products? What would that look like code-wise?</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Rule
&nbsp;
  has_many <span style="color:#ff3333; font-weight:bold;">:products</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Hmm&#8230; looks perverted, (a rule has products?) but let&#8217;s keep going with some pseudo code.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">product = rule.<span style="color:#9900CC;">products</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Cheese'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'cost'</span>, <span style="color:#ff3333; font-weight:bold;">:value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>I dig the second part:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'cost'</span>, <span style="color:#ff3333; font-weight:bold;">:value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>So let&#8217;s keep that in mind as we progress.</p>
<p>But what about rule.products? Our first line of code tells us that products should be able to evaluate rules, so there&#8217;s gotta be some connection between the two. What do we know least about? I&#8217;d probably say the rule objects themselves right now, so let&#8217;s take a stab at designing one.</p>
<p>What are rules? Well, let&#8217;s look at a real-life example.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&#40;</span>x <span style="color:#006600; font-weight:bold;">+</span> y<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">*</span> z</pre></td></tr></table></div>

<p>What do you see? &#8230; You could say you see a simple math formula. Perhaps, if you recall David West&#8217;s explanation of self-evaluating objects, you see an array of operators and variables. Before I tell you what I see, I&#8217;d like to say that what I see is based off my previous experience handling self-evaluating objects. That said, I see a string.</p>
<p>That&#8217;s it. A simple string.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#996600;">&quot;(x + y) * z&quot;</span></pre></td></tr></table></div>

<p>It&#8217;s so simple it&#8217;s obvious. And obvious things are often the most difficult thing to see. Now that we know what a rule <em>is</em>, let&#8217;s try and define it using object parlance. What can a rule <em>do</em>? What&#8217;s it comprised of? What are its responsibilities? Who must it collaborate with to get its job done?</p>
<p>The first thing I see is a definition. Every rule has a definition. I suppose also, that a rule could have a name; it would certainly make distinguishing one rule from another easier.</p>
<p>So now we have named rules with definitions. Let&#8217;s see some potential code.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">rule = Rule.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Product cost'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
rule.<span style="color:#9900CC;">definition</span> = <span style="color:#996600;">'(cost * tax) + cost'</span></pre></td></tr></table></div>

<p>Looks pretty clean. What next? Oh, that&#8217;s right, the obvious: a rule can <em>evaluate</em> itself. Ah, there&#8217;s the meat. Now we have a new, non AR-inherited responsibility: evaluation. Let&#8217;s take a look..</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Rule <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> evaluate
    <span style="color:#CC0066; font-weight:bold;">eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>definition<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>That&#8217;d be nice if that&#8217;s all we had to do. Unfortunately it&#8217;s not. Executing that as is will raise an error. If we think back to our earlier work, we did simple string replacement to get the proper values into our definitions.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> evaluate
  definition.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'uh oh!'</span>, <span style="color:#996600;">&quot;we're missing something&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Things just got interesting. Our rule doesn&#8217;t have access to the variables needed for substitution in its definition. Hmm&#8230; let&#8217;s stop and think for a moment.</p>
<p>Rules, products and variables. Products have variables for use in rules. A rule&#8217;s definition must have its variables substituted out for actual values. What does that look like?</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">rule = Rule.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Product cost'</span>, <span style="color:#ff3333; font-weight:bold;">:definition</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'(cost * tax) + cost'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
rule.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>Hmm&#8230; that could work. A rule requires a product be passed to it to gather the contents of its variables.</p>
<p>Let&#8217;s try that.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Rule <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> evaluate<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>
    product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>variable<span style="color:#006600; font-weight:bold;">|</span>
      definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span>variable.<span style="color:#9900CC;">name</span>, variable.<span style="color:#9900CC;">value</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#CC0066; font-weight:bold;">eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>definition<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Not bad. A rule can evaluate itself in the context of a given product&#8217;s variables. This will work provide the product passed has all the variables required of the rule, and vice versa.</p>
<p>Of course, this model doesn&#8217;t look like our original diagram, and that&#8217;s okay. Things rarely go according to plan. Let&#8217;s review what we&#8217;ve done so far.</p>
<p>Rule objects stand alone. They are named mathematical definitions that evaluate in the context of a given product. (In reality, &#8216;product&#8217; could be any object that responds to a variables method.)</p>
<p>So our end result is now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">rule.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>That&#8217;s the opposite of what I originally proposed (product.evaluate(rule)), and I&#8217;ll be honest; it feels weird. On the bright side, this solution is much simpler than my original Rails version. However, I still like the feel of:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">product.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>rule<span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>But hey, whatever works, right? There&#8217;s just one more thing&#8230; rules within rules. Ah, interesting. What would that look like?</p>
<p>Well, actually, it shouldn&#8217;t look any different than what we have now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">rule.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>The above should still give us a single number. So it&#8217;s not the end-result (API) code that will be changing, it&#8217;s our internal code that will change. But how? Let&#8217;s take a look at our definition.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&#40;</span>cost <span style="color:#006600; font-weight:bold;">*</span> tax<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> cost</pre></td></tr></table></div>

<p>The part in parentheses represents the tax of our product. So we&#8217;re really saying:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">tax <span style="color:#006600; font-weight:bold;">+</span> cost</pre></td></tr></table></div>

<p>But now we&#8217;ve run into a problem. Is tax a rule or a variable? Currently there&#8217;s no way to know the difference. How can we solve that? We need to be able to differentiate between rules and variables. Or at least, I think we should.</p>
<p>We <em>could</em> not, and simply perform blind string replacement, replacing everything in our definition with every match in our variables method. The result is a definition where the only non-numeric or operator characters must be rules. But that sounds pretty flimsy. I can easily see there being a tax variable and a tax rule. So let&#8217;s make clear the difference between rules and variables.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">r:tax <span style="color:#006600; font-weight:bold;">+</span> v:cost</pre></td></tr></table></div>

<p>Heh, that works. It changes our replacement around a bit, but not too much.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> evaluate<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>
  product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>variable<span style="color:#006600; font-weight:bold;">|</span>
    definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'v:'</span> <span style="color:#006600; font-weight:bold;">+</span> variable.<span style="color:#9900CC;">name</span>, variable.<span style="color:#9900CC;">value</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#CC0066; font-weight:bold;">eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>definition<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Okay, so we can still evaluate our variables. But what about other rules? What do we do when we encounter another rule? Let&#8217;s try scanning the string for instances of r:xxx, do a find for that rule name, and then call evaluate on it&#8230;</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> evaluate<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># Operate on a copy of the definition so the original is open to variable</span>
    <span style="color:#008000; font-style:italic;"># changes.</span>
    evaluated_definition = definition.<span style="color:#9900CC;">dup</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Recursively evaluate any rules in the definition.</span>
    evaluated_definition.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>r:\w<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>match<span style="color:#006600; font-weight:bold;">|</span>
      evaluated_definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span>match, Rule.<span style="color:#9900CC;">find_by_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>match<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span>, match.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Replace variables in the definition with values provided by product.</span>
    product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>variable<span style="color:#006600; font-weight:bold;">|</span>
      evaluated_definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'v:'</span> <span style="color:#006600; font-weight:bold;">+</span> variable.<span style="color:#9900CC;">name</span>, variable.<span style="color:#9900CC;">value</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Evaluate the fully-substituted string.</span>
    <span style="color:#CC0066; font-weight:bold;">eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>evaluated_definition<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Let&#8217;s run this! (You&#8217;ll need to download the complete Rails app and follow the directions in doc/readme.)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">rule = Rule.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Product cost'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
rule.<span style="color:#9900CC;">definition</span> = <span style="color:#996600;">'r:tax + v:cost'</span>
rule2 = Rule.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'tax'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
rule2.<span style="color:#9900CC;">definition</span> = <span style="color:#996600;">'(v:cost * v:tax)'</span>
rule.<span style="color:#9900CC;">save</span>
rule2.<span style="color:#9900CC;">save</span>
&nbsp;
product = Product.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Cheese'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'cost'</span>, <span style="color:#ff3333; font-weight:bold;">:value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'tax'</span>, <span style="color:#ff3333; font-weight:bold;">:value</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0.05</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
rule.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; 10.5</span></pre></td></tr></table></div>

<p>Scha-weet! But wait! Do I see a recursive function in there? I sure do! Let&#8217;s deconstruct it.</p>
<p>We have a rule. We scan its definition for strings that look like r:xxx. Once found, we perform a global string replacement on it, using r:xxx as the pattern match, with the substitute string being the return value of calling evaluate on the rule referenced by r:xxx.</p>
<p>Was that confusing? Don&#8217;t worry if it was. Recursion can be pretty difficult to wrap your head around, especially if you didn&#8217;t write it. If you&#8217;re determined to understand, I suggest reading it several times, line by line, very slowly. It may also help to add some puts messages in there and run it a few times in IRB. That way you can &#8220;watch&#8221; the recursion magic.</p>
<p>Anywho, just know that it works, and will go as deep as you need it to.</p>
<p>So there we have it! A fully Rails-based self-evaluating monster that will slay accountants everywhere! Okay not really, but it&#8217;s pretty cool nonetheless, right?</p>
<p>As excited as you may be, don&#8217;t lose yourself. It still only works in console. If you choose to use a solution like this you&#8217;ll still need to build an interface for people to use it. There are some other small issues, too. Rule names, for instance. The way the evaluate method is written, you can&#8217;t have multiple rules with the same name. Well, you could, but you&#8217;d only ever be able to access the first one. There&#8217;s also the rigidity of relationships. Product specifically defines its relationship to variables, and there&#8217;s still the (I consider) perversion of calling rule.evaluate(product). I&#8217;d love to see product.evaluate(rule).</p>
<p>That, however, is an exercise I leave to you. ;)</p>
<p>Oh, before I go, here&#8217;s the complete code listing:</p>
<p><strong>rule.rb</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Rule <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Answers with a BigDecimal after recursively solving rule definitions,</span>
  <span style="color:#008000; font-style:italic;"># performing variable replacement and finally evaluating a flat formula.</span>
  <span style="color:#008000; font-style:italic;">#</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> evaluate<span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># Operate on a copy of the definition so the original is open to variable</span>
    <span style="color:#008000; font-style:italic;"># changes.</span>
    evaluated_definition = definition.<span style="color:#9900CC;">dup</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Recursively evaluate any rules in the definition.</span>
    evaluated_definition.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>r:\w<span style="color:#006600; font-weight:bold;">+/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>match<span style="color:#006600; font-weight:bold;">|</span>
      evaluated_definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span>match, Rule.<span style="color:#9900CC;">find_by_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>match<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span>, match.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">evaluate</span><span style="color:#006600; font-weight:bold;">&#40;</span>product<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Replace variables in the definition with values provided by product.</span>
    product.<span style="color:#9900CC;">variables</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>variable<span style="color:#006600; font-weight:bold;">|</span>
      evaluated_definition.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'v:'</span> <span style="color:#006600; font-weight:bold;">+</span> variable.<span style="color:#9900CC;">name</span>, variable.<span style="color:#9900CC;">value</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Evaluate the fully-substituted string.</span>
    <span style="color:#CC0066; font-weight:bold;">eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>evaluated_definition<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><strong>product.rb</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Product <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  has_many <span style="color:#ff3333; font-weight:bold;">:variables</span>, <span style="color:#ff3333; font-weight:bold;">:dependent</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:destroy</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><strong>variable.rb</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Variable <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  belongs_to <span style="color:#ff3333; font-weight:bold;">:product</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><strong>schema.rb</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">ActiveRecord::Schema</span>.<span style="color:#9900CC;">define</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:version</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  create_table <span style="color:#996600;">&quot;products&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;name&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:string</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  create_table <span style="color:#996600;">&quot;rules&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;name&quot;</span>,       <span style="color:#ff3333; font-weight:bold;">:string</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;definition&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:string</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  create_table <span style="color:#996600;">&quot;variables&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;product_id&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:integer</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;name&quot;</span>,       <span style="color:#ff3333; font-weight:bold;">:string</span>
    t.<span style="color:#9900CC;">column</span> <span style="color:#996600;">&quot;value&quot;</span>,      <span style="color:#ff3333; font-weight:bold;">:decimal</span>, <span style="color:#ff3333; font-weight:bold;">:precision</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">8</span>, <span style="color:#ff3333; font-weight:bold;">:scale</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">2</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.rabbitcreative.com/2007/06/23/discovering-self-evaluating-objects-in-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

