<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>skim</title>
 
 <link href="http://skim.la/" />
 <updated>2012-02-12T13:18:59-08:00</updated>
 <id>http://skim.la/</id>
 <author>
   <name>skim</name>
 </author>
 
 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/sl4m" /><feedburner:info uri="sl4m" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>things you should know about javascript</title>
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/KBF1ehyaxB0/things-you-should-know-about-javascript" />
   <updated>2012-02-06T07:00:00-08:00</updated>
   <id>http://skim.la/2012/02/06/things-you-should-know-about-javascript</id>
   <content type="html">&lt;p&gt;
  Note: this post originally appeared on 8th Light's website.
&lt;/p&gt;

&lt;h2&gt;
  I know some people cringe at the idea of writing JavaScript.
  They opt to write CoffeeScript instead and make every attempt
  to avoid looking at those funny looking mustaches.
&lt;/h2&gt;
&lt;p&gt;
  It is however, advantageous to learn JavaScript and learn the
  advanced features, even the odd things about the language.
  Here’s a collection of things you should know:
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Short-hand syntax for creating Arrays and Objects&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      Prefer to use &lt;code&gt;[]&lt;/code&gt; for arrays and &lt;code&gt;{}&lt;/code&gt;
      for objects instead of &lt;code&gt;new Array()&lt;/code&gt; and &lt;code&gt;new Object()&lt;/code&gt;.
    &lt;/p&gt;
    &lt;p&gt;
      Other than being syntactically shorter, particularly
      &lt;code&gt;new Array()&lt;/code&gt; yields different results depending on the
      arguments you provide.
    &lt;/p&gt;
    &lt;p&gt;
      Passing a single &lt;code&gt;Number&lt;/code&gt; argument will change the
      length of the array after instantiation.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 2&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      I’m not sure why you would do this because arrays in
      JavaScript are dynamic.  Passing in a single argument
      that is not a &lt;code&gt;Number&lt;/code&gt; or passing more than one argument
      will instantiate the array with the arguments provided.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;array1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;array1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// [true]&lt;/span&gt;

      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;array2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
      &lt;span class="nx"&gt;array2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// [1, &amp;quot;a&amp;quot;, {}]&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      Objects are easier to build when using the short-hand syntax.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;key1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;value1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;value2&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;value1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;value2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;dot notation vs. subscript notation (bracket notation)&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      You can call properties/methods using dot notation or subscript notation.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 42&lt;/span&gt;
      &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  &lt;span class="c1"&gt;// 42&lt;/span&gt;
      &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;hello world&amp;quot;&lt;/span&gt;
      &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fn&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;hello world&amp;quot;&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      You might ask why you'd ever want to use subscript notation.
      Subscript notation allows for dynamic creation of properties and methods.
      So if you ever do any sort of metaprogramming, you'll most likely be
      using the subscript notation.
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;=== and !===&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      CoffeeScript has this right.  Prefer &lt;code&gt;===&lt;/code&gt; and &lt;code&gt;!==&lt;/code&gt;
      over &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;.  The reason for this is due to
      type coercion when using the equality operator.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
      &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
      &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
      &lt;span class="s2"&gt;&amp;quot; \t\r\n&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      JavaScript considers &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;""&lt;/code&gt; to be falsy unlike Ruby.
      If the strict equality operator (&lt;code&gt;===&lt;/code&gt;) was used in the above examples,
      they would all return false.
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Function Scope, The Only Scope&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;SomeObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      What is the value of &lt;code&gt;SomeObject&lt;/code&gt; outside of the &lt;code&gt;if&lt;/code&gt; statement?
      Is it &lt;code&gt;undefined&lt;/code&gt;?  Or &lt;code&gt;{}&lt;/code&gt;?
    &lt;/p&gt;
    &lt;p&gt;
      Believe it or not, code wrapped in m̶u̶s̶t̶a̶c̶h̶e̶s̶ &lt;b&gt;curly braces&lt;/b&gt;
      does not have scope.  Only functions create scope.  Therefore,
      &lt;code&gt;SomeObject&lt;/code&gt; is &lt;code&gt;{}&lt;/code&gt;.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ReferenceError&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Hoisting&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;SomeObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;SomeObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      For this example, what is the value of &lt;code&gt;SomeObject&lt;/code&gt;?
      Is it &lt;code&gt;undefined&lt;/code&gt;?  Or &lt;code&gt;{}&lt;/code&gt;?  Or some &lt;code&gt;Error&lt;/code&gt;?
      This is probably one of the most interesting parts of JavaScript.  Right
      before the code is executed, all variable declarations are
      &lt;i&gt;hoisted&lt;/i&gt; to the top of the given scope.  The example above
      turns into this before execution:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;SomeObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;SomeObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;SomeObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      So, the value of &lt;code&gt;SomeObject&lt;/code&gt; is &lt;code&gt;{}&lt;/code&gt;.  Similarly, function
      declarations are &lt;i&gt;hoisted&lt;/i&gt; to the top as well.  This example:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="nx"&gt;abracadabra&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;abracadabra&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;magic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;it works!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      works because it looks like this before execution:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;abracadabra&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;magic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;it works!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;abracadabra&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      It's magic!
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Casting Values&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      There are several ways to cast a primitive value.
      The simplest way is to use the &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Number&lt;/code&gt;,
      &lt;code&gt;Boolean&lt;/code&gt; functions:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;42&amp;quot;&lt;/span&gt;
      &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;42&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 42&lt;/span&gt;
      &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      Cool kids like to use this approach, which works the same way:
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="c1"&gt;// cast string to number using the plus operator&lt;/span&gt;
      &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;42&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 42&lt;/span&gt;

      &lt;span class="c1"&gt;// cast number to string using an empty string and coercion&lt;/span&gt;
      &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;42&amp;quot;&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Using Number methods on Number literals&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      Ever wondered why you can call &lt;code&gt;String&lt;/code&gt; methods on &lt;code&gt;String&lt;/code&gt;
      literals, but not &lt;code&gt;Numbers&lt;/code&gt;?
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="s2"&gt;&amp;quot;1 2 3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// [&amp;quot;1&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;3&amp;quot;]&lt;/span&gt;

      &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// SyntaxError&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
    &lt;p&gt;
      According to the JavaScript Garden documentation, it's
      because &lt;i&gt;a flaw in JavaScript's parser tries to parse
      the dot notation on a number as a floating point literal&lt;/i&gt;.
      The best way to handle this issue is to wrap the &lt;code&gt;Number&lt;/code&gt;
      literal in parentheses.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;2&amp;quot;&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;arguments object is not an Array&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      The &lt;code&gt;arguments&lt;/code&gt; object has a &lt;code&gt;length&lt;/code&gt; property, but
      it is not an &lt;code&gt;Array&lt;/code&gt;.  Therefore, you cannot
      directly call &lt;code&gt;Array&lt;/code&gt; methods from the &lt;code&gt;arguments&lt;/code&gt;
      object.  The best way to do this is to use &lt;code&gt;call&lt;/code&gt;
      or &lt;code&gt;apply&lt;/code&gt;.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;b&gt;Privatizing variables&lt;/b&gt;&lt;/p&gt;
    &lt;p&gt;
      With closure, you can create privatized variables
      in JavaScript.
    &lt;/p&gt;
    &lt;p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;privatizedVariable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;private&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;privatizedVariable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;})();&lt;/span&gt;

      &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;quot;private&amp;quot;&lt;/span&gt;
      &lt;span class="nx"&gt;privatizedVariable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// ReferenceError&lt;/span&gt;
      
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

    &lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  There are a ton more advanced features that everyone
  should know that are outside the scope of this post
  (or my lack of explaining it better than the
  books/articles out there):
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Prototypal inheritance&lt;/li&gt;
  &lt;li&gt;call and apply&lt;/li&gt;
  &lt;li&gt;function expressions vs. function declarations vs. named function expressions&lt;/li&gt;
  &lt;li&gt;Name Resolution Order&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  You can read more about them below.
&lt;/p&gt;
&lt;p&gt;
  Master your JavaScript-Fu.  Enjoy.
&lt;/p&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;a href="http://bonsaiden.github.com/JavaScript-Garden/"&gt;JavaScript Garden&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://shichuan.github.com/javascript-patterns/"&gt;JavaScript Patterns&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting"&gt;JavaScript Scoping and Hoisting&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://dmitry.baranovskiy.com/post/91403200"&gt;Dmitry's JavaScript Quiz&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://perfectionkills.com/javascript-quiz/"&gt;Kangax's JavaScript Quiz&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://kangax.github.com/nfe/"&gt;Named Function Expressions Demystified&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Douglas Crockford's JavaScript: The Good Parts
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://blog.caplin.com/2012/01/27/the-why-of-wat/"&gt;Why of WAT&lt;/a&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/KBF1ehyaxB0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2012/02/06/things-you-should-know-about-javascript</feedburner:origLink></entry>
 
 <entry>
   <title>rsa public key interoperability between ruby and android</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="java" />
   
   <category term="--" />
   
   <category term="android" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/Ig92hoJCfeA/rsa-public-key-interoperability-between-ruby-and-android" />
   <updated>2012-01-16T05:00:00-08:00</updated>
   <id>http://skim.la/2012/01/16/rsa-public-key-interoperability-between-ruby-and-android</id>
   <content type="html">&lt;p&gt;I recently worked on a project where sensitive information needed to be sent from an Android app to a Ruby-based server. Our solution was to use asymmetric encryption (the actual implementation was more involved, but for the sake of simplicity, let&amp;#8217;s just focus on asymmetric encryption, namely RSA). Using an RSA key pair generated by the Ruby-based server, the Android app encrypted sensitive information using the RSA public key and the server decrypted the sensitive data using the RSA private key. This sounds straightforward, but what I&amp;#8217;m going to talk about here is an issue when using an RSA public key generated from pre-Ruby 1.9.3 in an Android app and several solutions to work around the issue.&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;p&gt;Solutions to this problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the server side, encode pre-Ruby 1.9.3 RSA public keys using the X.509 format &amp;#8211; &lt;a href='https://gist.github.com/1470360'&gt;gist&lt;/a&gt; (thanks &lt;a href='http://twitter.com/!#/_emboss_'&gt;Martin&lt;/a&gt;!).&lt;/li&gt;

&lt;li&gt;Android Standard Library comes with a crippled version of BouncyCastle. Grab the full version of &lt;a href='http://www.bouncycastle.org/java.html'&gt;BouncyCastle&lt;/a&gt; and grab the classes necessary to extract the exponent and modulus of the PKCS#1 encoded public key to create a PublicKey object &amp;#8211; &lt;a href='https://gist.github.com/1617144'&gt;gist&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='rsa_public_key_encoded_format_problem_in_preruby_193'&gt;RSA Public Key Encoded Format Problem in pre-Ruby 1.9.3&lt;/h2&gt;

&lt;p&gt;The Ruby-based server generates the RSA key pair and stores the RSA private key in its database. If you know RSA, you know if you have the private key, you can easily generate its public key counterpart, but not vice versa. Using the public key given by the server, I attempted to load it in the Android app.&lt;/p&gt;

&lt;p&gt;In Ruby, you can simply load up a public key by passing it to &lt;code&gt;OpenSSL::PKey::RSA::new&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;openssl&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;public_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;MIIBCgKCAQEA20O377QEiZvPsj14LKl2xO23iirJB5WDTVjeab1cIOJu1vbV+Pdwl1Bov8m896ZG4K0S/qvfJcdHLovr2WJ+o2maK1XZCNy8lA&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;zIPzZrj/yDZAB2GSjR3in1lQRQPtWjIOdB8Cy2FGybEstIkpf8MD3XMWp5g8BtdOv43ekjBuTiGGLlPRG0+IiazjHlWjyl6DU9x9m2Jxks0H6YZud6zf4s9Q6&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;9vPUYgOZXWs7IghxqrVGE5mWxoRudsDFhLYP706+IrSxGOf5fE0/8fjtzj/eJayCLmkUWq/xsts5tBAbwsX5xKdk8iD0OU2qOEbVuiYmehEiJnvO2vyd+t76C&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;xwIDAQAB&amp;quot;&lt;/span&gt;

&lt;span class='n'&gt;rsa_public_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;PKey&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RSA&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;decode64&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;public_key&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, in Android, it&amp;#8217;s a bit more complex (oh, Java!). You have to first get an instance of &lt;code&gt;KeyFactory&lt;/code&gt;, create an &lt;code&gt;X509EncodedKeySpec&lt;/code&gt;, pass in the public key string, then generate the public key using that key spec.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='n'&gt;PublicKey&lt;/span&gt; &lt;span class='nf'&gt;getPublicKey&lt;/span&gt;&lt;span class='o'&gt;()&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;publicKey&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;MIIBCgKCAQEA20O377QEiZvPsj14LKl2xO23iirJB5WDTVjeab1cIOJu1vbV+Pdwl1Bov8m896ZG4K0S/qvfJcdHLovr2WJ+&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s'&gt;&amp;quot;o2maK1XZCNy8lAzIPzZrj/yDZAB2GSjR3in1lQRQPtWjIOdB8Cy2FGybEstIkpf8MD3XMWp5g8BtdOv43ekjBuTiGGLlPRG0+IiazjHlWjyl6DU&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s'&gt;&amp;quot;9x9m2Jxks0H6YZud6zf4s9Q69vPUYgOZXWs7IghxqrVGE5mWxoRudsDFhLYP706+IrSxGOf5fE0/8fjtzj/eJayCLmkUWq/xsts5tBAbwsX5xKd&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
            &lt;span class='s'&gt;&amp;quot;k8iD0OU2qOEbVuiYmehEiJnvO2vyd+t76CxwIDAQAB&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
        &lt;span class='n'&gt;KeyFactory&lt;/span&gt; &lt;span class='n'&gt;keyFactory&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;KeyFactory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getInstance&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;RSA&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
        &lt;span class='n'&gt;X509EncodedKeySpec&lt;/span&gt; &lt;span class='n'&gt;encodedPubKeySpec&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;X509EncodedKeySpec&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;decode&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;publicKey&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;NO_WRAP&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;keyFactory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;generatePublic&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;encodedPubKeySpec&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;NoSuchAlgorithmException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;InvalidKeySpecException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
      &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, this raises an &lt;code&gt;InvalidKeySpecException&lt;/code&gt;. Countless Google queries resulting in many hours of yak shaving, led me to dead ends. It was when I kicked off a &lt;code&gt;Ruby 1.9.3&lt;/code&gt; irb instance that showed me the light.&lt;/p&gt;

&lt;h2 id='rsa_encoded_format_in_ruby_193'&gt;RSA Encoded Format in Ruby 1.9.3&lt;/h2&gt;

&lt;p&gt;In a &lt;code&gt;Ruby 1.9.3&lt;/code&gt; irb instance, I loaded the same public key I generated from &lt;code&gt;Ruby 1.8.7&lt;/code&gt; and to my surprise, noticed the public key changed in the front of my eyes.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;openssl&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;public_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;MIIBCgKCAQEA20O377QEiZvPsj14LKl2xO23iirJB5WDTVjeab1cIOJu1vbV+Pdwl1Bov8m896ZG4K0S/qvfJcdHLovr2WJ+o2maK1XZCNy8lA&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;zIPzZrj/yDZAB2GSjR3in1lQRQPtWjIOdB8Cy2FGybEstIkpf8MD3XMWp5g8BtdOv43ekjBuTiGGLlPRG0+IiazjHlWjyl6DU9x9m2Jxks0H6YZud6zf4s9Q6&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;9vPUYgOZXWs7IghxqrVGE5mWxoRudsDFhLYP706+IrSxGOf5fE0/8fjtzj/eJayCLmkUWq/xsts5tBAbwsX5xKdk8iD0OU2qOEbVuiYmehEiJnvO2vyd+t76C&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
  &lt;span class='s2'&gt;&amp;quot;xwIDAQAB&amp;quot;&lt;/span&gt;

&lt;span class='n'&gt;rsa_public_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;PKey&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RSA&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;decode64&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;public_key&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='c1'&gt;# strip newlines and begin/end markers&lt;/span&gt;
&lt;span class='n'&gt;new_public_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;rsa_public_key&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gsub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gsub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/-----(BEGIN|END) PUBLIC KEY-----/&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='c1'&gt;# =&amp;gt; &amp;quot;MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA20O377QEiZvPsj14LKl2xO23iirJB5WDTVjeab1cIOJu1vbV+Pdwl1Bov8m896ZG4K0S/qvfJcdHLovr2WJ+o2maK1XZCNy8lAzIPzZrj/yDZAB2GSjR3in1lQRQPtWjIOdB8Cy2FGybEstIkpf8MD3XMWp5g8BtdOv43ekjBuTiGGLlPRG0+IiazjHlWjyl6DU9x9m2Jxks0H6YZud6zf4s9Q69vPUYgOZXWs7IghxqrVGE5mWxoRudsDFhLYP706+IrSxGOf5fE0/8fjtzj/eJayCLmkUWq/xsts5tBAbwsX5xKdk8iD0OU2qOEbVuiYmehEiJnvO2vyd+t76CxwIDAQAB&amp;quot;&lt;/span&gt;

&lt;span class='n'&gt;new_public_key&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;public_key&lt;/span&gt;
&lt;span class='c1'&gt;# =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I tried to see if &lt;code&gt;Ruby 1.9.2&lt;/code&gt; produced the same results; the public key was the same as 1.8.7. I then tried generating a new public key in &lt;code&gt;Ruby 1.9.3&lt;/code&gt;, then initialize that key in another &lt;code&gt;OpenSSL::PKey::RSA&lt;/code&gt; instance in 1.9.3, but the key was identical. This led me to believe that something changed in &lt;code&gt;Ruby 1.9.3&lt;/code&gt; that is not in &lt;code&gt;Ruby 1.8.7/Ruby 1.9.2&lt;/code&gt;. I searched on Google again for clues and fortunately found something relevant. &lt;a href='https://twitter.com/#!/_emboss_'&gt;Martin Bo&amp;#223;let&amp;#8217;s&lt;/a&gt; filed a &lt;a href='http://bugs.ruby-lang.org/issues/show/4421'&gt;bug report&lt;/a&gt; for Ruby 1.9.3; in the report, he describes how the encoded format for RSA public keys was not the default format used by OpenSSL, but rather the encoding format specified by PKCS#1. The &lt;a href='http://bugs.ruby-lang.org/projects/ruby-trunk/repository/diff/ext/openssl/ossl_pkey_rsa.c?rev=31520&amp;amp;type=inline'&gt;fix&lt;/a&gt; shows Martin changing &lt;code&gt;PEM_read_bio_RSAPublicKey&lt;/code&gt; to &lt;code&gt;PEM_read_bio_RSA_PUBKEY&lt;/code&gt;. Perusing in the &lt;a href='http://www.openssl.org/docs/crypto/pem.html'&gt;OpenSSL documentation&lt;/a&gt; shows what Martin was describing in the bug report: &lt;code&gt;RSAPublicKey&lt;/code&gt; encodes the public key using the PKCS#1 &lt;code&gt;RSAPublicKey&lt;/code&gt; structure rather than the &lt;code&gt;SubjectPublicKeyInfo&lt;/code&gt; structure. The former structure is not compatible with the crypto library available in Android.&lt;/p&gt;

&lt;p&gt;The fix has been applied to &lt;code&gt;Ruby-1.9.3-p0&lt;/code&gt;, but the problem is still present for all Ruby versions prior. This means the Ruby-based server is still affected and the path to upgrading to 1.9.3 for us was not an option. I needed to approach the problem differently and reached out to Martin for some assistance. He was extremely helpful and came up with this solution.&lt;/p&gt;

&lt;h2 id='solution_1_encode_preruby_193_rsa_public_keys_using_the_x509_format_gist'&gt;Solution #1: Encode pre-Ruby 1.9.3 RSA public keys using the X.509 format (&lt;a href='https://gist.github.com/1470360'&gt;gist&lt;/a&gt;)&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;openssl&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;rsa&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;PKey&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RSA&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2048&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;modulus&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;rsa&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;
&lt;span class='n'&gt;exponent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;rsa&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;e&lt;/span&gt;

&lt;span class='n'&gt;oid&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ObjectId&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;rsaEncryption&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;alg_id&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Sequence&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;oid&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Null&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;ary&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='nb'&gt;Integer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;modulus&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='nb'&gt;Integer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;exponent&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='n'&gt;pub_key&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Sequence&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;ary&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;enc_pk&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;BitString&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pub_key&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_der&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;subject_pk_info&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ASN1&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Sequence&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;alg_id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;enc_pk&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='n'&gt;base64&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;encode64&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;subject_pk_info&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_der&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='c1'&gt;#This is the equivalent to the X.509 encoding used in &amp;gt;= 1.9.3&lt;/span&gt;
&lt;span class='n'&gt;pem&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;-----BEGIN PUBLIC KEY-----&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;base64&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;-----END PUBLIC KEY-----&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Martin basically wrote the X.509 encoding format from scratch. This would have worked for us, but unfortunately, we have already issued RSA public keys to customers and needed to support the PKCS#1 encoded format public keys.&lt;/p&gt;

&lt;p&gt;I googled some more and found a &lt;a href='http://stackoverflow.com/a/4033421'&gt;solution&lt;/a&gt; that extracts the &lt;a href='http://en.wikipedia.org/wiki/RSA_(algorithm)#Key_generation'&gt;exponent and modulus&lt;/a&gt; from the public key. With the exponent and modulus, I can create a PublicKey object.&lt;/p&gt;

&lt;h2 id='solution_2_full_version_of_bouncycastle_and_rsapublickeystructure_gist'&gt;Solution #2: Full Version of BouncyCastle and RSAPublicKeyStructure (&lt;a href='https://gist.github.com/1617144'&gt;gist&lt;/a&gt;)&lt;/h2&gt;

&lt;p&gt;This solution requires classes that are not available in the Android Standard Library. A Google &lt;a href='http://code.google.com/p/android/issues/detail?id=3280'&gt;result&lt;/a&gt; provides details about the problem with the Android Standard Library&amp;#8217;s crippled version of BouncyCastle. To remedy this problem, grab the full version of BouncyCastle and bring in only the required classes to extract the exponent and modulus of the public key string.&lt;/p&gt;

&lt;p&gt;After adding BouncyCastle classes, I created a static method that reads pre-Ruby 1.9.3 public keys, extracts the exponent and modulus, and returns a PublicKey object:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.IOException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.security.KeyFactory&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.security.NoSuchAlgorithmException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.security.PublicKey&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.security.spec.InvalidKeySpecException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.security.spec.RSAPublicKeySpec&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.bouncycastle.asn1.ASN1InputStream&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.bouncycastle.asn1.DERObject&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.bouncycastle.asn1.x509.RSAPublicKeyStructure&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;org.bouncycastle.util.encoders.Base64&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;

&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;RSAUtil&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='n'&gt;PublicKey&lt;/span&gt; &lt;span class='nf'&gt;publicKey&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;publicKeyString&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='kt'&gt;byte&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;decodedPublicKey&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;Base64&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;decode&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;publicKeyString&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;ASN1InputStream&lt;/span&gt; &lt;span class='n'&gt;in&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;ASN1InputStream&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;decodedPublicKey&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;DERObject&lt;/span&gt; &lt;span class='n'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;readObject&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
            &lt;span class='n'&gt;RSAPublicKeyStructure&lt;/span&gt; &lt;span class='n'&gt;keyStruct&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;RSAPublicKeyStructure&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getInstance&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;obj&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='n'&gt;RSAPublicKeySpec&lt;/span&gt; &lt;span class='n'&gt;keySpec&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;RSAPublicKeySpec&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;keyStruct&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getModulus&lt;/span&gt;&lt;span class='o'&gt;(),&lt;/span&gt; &lt;span class='n'&gt;keyStruct&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getPublicExponent&lt;/span&gt;&lt;span class='o'&gt;());&lt;/span&gt;
            &lt;span class='n'&gt;KeyFactory&lt;/span&gt; &lt;span class='n'&gt;keyFactory&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;KeyFactory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;getInstance&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;RSA&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;keyFactory&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;generatePublic&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;keySpec&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;NoSuchAlgorithmException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;InvalidKeySpecException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IOException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
            &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt;
        &lt;span class='o'&gt;}&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is definitely a unique cryptography issue between Ruby and Android. As far as I know, the Ruby team has no plans to backport the &lt;code&gt;Ruby 1.9.3&lt;/code&gt; fix into prior Ruby versions, but the solutions I have presented should be sufficient for your needs to make public keys interoperable between Ruby and Android. Feel free to comment if you have any questions or different solutions to this problem.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/Ig92hoJCfeA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2012/01/16/rsa-public-key-interoperability-between-ruby-and-android</feedburner:origLink></entry>
 
 <entry>
   <title>mac os x lion development environment</title>
   
   <category term="--" />
   
   <category term="environment" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/67VfrcgN9Vg/mac-os-x-lion-development-environment" />
   <updated>2011-11-13T12:00:00-08:00</updated>
   <id>http://skim.la/2011/11/13/mac-os-x-lion-development-environment</id>
   <content type="html">&lt;p&gt;I finally bit the bullet and installed Lion on my Macbook Pro. Mac OS X Lion released almost four months ago and comes with some interesting features. You can read about them in detail &lt;a href='http://en.wikipedia.org/wiki/Mac_OS_X_Lion'&gt;here&lt;/a&gt;. What I&amp;#8217;m going to write about here are some of the hurdles I had to overcome. Perhaps when it&amp;#8217;s time for you to upgrade, you won&amp;#8217;t have to experience them. Of course, YMMV.&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time Machine does not work if FileVault is enabled&lt;/li&gt;

&lt;li&gt;Use encrypted disk images or TrueCrypt instead of FileVault&lt;/li&gt;

&lt;li&gt;Lion Disk Utility detects if hard drive has too many &lt;a href='http://en.wikipedia.org/wiki/S.M.A.R.T.'&gt;S.M.A.R.T.&lt;/a&gt; errors and simply refuses to install Lion if so&lt;/li&gt;

&lt;li&gt;Had to replace hard drive (should have purchased SSD, c&amp;#8217;est la vie)&lt;/li&gt;

&lt;li&gt;XCode 4.2 is not rvm/homebrew friendly. Have to use &lt;a href='https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.1_for_lion/xcode_4.1_for_lion.dmg'&gt;XCode 4.1&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;XCode 4.1 installer installs &lt;code&gt;Install XCode.app&lt;/code&gt; in your Applications folder. You then have to install &lt;code&gt;Install XCode.app&lt;/code&gt; to install XCode. Not confusing at all.&lt;/li&gt;

&lt;li&gt;Homebrew does not have a vim formula (not talking about macvim). Have to compile on your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='getting_ready'&gt;Getting Ready&lt;/h2&gt;

&lt;p&gt;I could have easily upgraded to Lion from Snow Leopard, but I wanted a clean slate. I collected a lot of cruft over the year and a half and I thought it would be educationally rewarding to set up the development environment again, but this time without a guide. I also wanted a clean &lt;a href='http://en.wikipedia.org/wiki/Dot-file'&gt;dot-file&lt;/a&gt; slate, learn about the commands in each dot-file instead of just accepting them and taking them for granted.&lt;/p&gt;

&lt;p&gt;If you already have Time Machine set up (or similar backup software), then you&amp;#8217;re already ahead of the game. I did not have any backup software installed/enabled (hard drives can fail???), so I manually copied directories and files over to my home NAS. I didn&amp;#8217;t have a lot of stuff that I cared to back up, so this was a rather easy process.&lt;/p&gt;

&lt;h2 id='lion_on_usb'&gt;Lion on USB&lt;/h2&gt;

&lt;p&gt;Since I planned to wipe out the hard drive and start fresh, I needed to store the Lion installer on a USB thumb drive. Apple offers a USB thumb drive option, but why pay $69 when you can do it for free? There are many guides out there with detailed instructions on how to extract the core file from Lion installer and transfer it to your USB thumb drive.&lt;/p&gt;

&lt;h2 id='lets_install'&gt;Let&amp;#8217;s Install&lt;/h2&gt;

&lt;p&gt;I rebooted the computer, inserted the thumb drive, and held down the Option key. I proceeded to the Disk Utility and wiped out my hard drive. Then when I attempted to install Mac OS X Lion, I was greeted with S.M.A.R.T. errors message. If you can&amp;#8217;t select the hard drive to tell the Lion installer the destination of your install, then chances are, you have S.M.A.R.T. errors. I googled this issue and lots of people have reported the same issue. The hard drive worked fine in Snow Leopard, Lion does not want to do anything with it.&lt;/p&gt;

&lt;p&gt;I ordered a new hard drive from Amazon.com, waited a day for it to arrive, then tried again. No S.M.A.R.T. errors. BOOM, it let me proceed and within 15 minutes, Lion was on my machine.&lt;/p&gt;

&lt;h2 id='post_install'&gt;Post Install&lt;/h2&gt;

&lt;p&gt;First thing I did was check for Software Updates because I was well aware of the updates that had come in post Lion release date. After that, I proceeded to install software I care about (in alphabetical order):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Briquette (Propane alternative for Campfire)&lt;/li&gt;

&lt;li&gt;Chrome&lt;/li&gt;

&lt;li&gt;iTerm&lt;/li&gt;

&lt;li&gt;Silverlight (Netflix)&lt;/li&gt;

&lt;li&gt;SizeUp (window sizing tool)&lt;/li&gt;

&lt;li&gt;Skype&lt;/li&gt;

&lt;li&gt;VLC&lt;/li&gt;

&lt;li&gt;VMWare Fusion&lt;/li&gt;

&lt;li&gt;Vox&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='development_environment'&gt;Development Environment&lt;/h2&gt;

&lt;p&gt;The following tools were installed to aid my development needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rvm (yes, I know about rbenv)&lt;/li&gt;

&lt;li&gt;homebrew&lt;/li&gt;

&lt;li&gt;XCode 4.1 (4.2 is evil)&lt;/li&gt;

&lt;li&gt;git&lt;/li&gt;

&lt;li&gt;vim (not macvim)&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/ChrisKempson/Vim-Tomorrow-Theme'&gt;Tomorrow Theme&lt;/a&gt; for vim&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/braintreeps/vim_dotfiles'&gt;vimfiles&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;ctags (for vim)&lt;/li&gt;

&lt;li&gt;zsh&lt;/li&gt;

&lt;li&gt;&lt;a href='https://github.com/zsh-users/zsh-syntax-highlighting'&gt;zsh-syntax-highlighting&lt;/a&gt; (fish shell-like support for zsh)&lt;/li&gt;

&lt;li&gt;tmux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know some hate rvm and prefer rbenv, but I&amp;#8217;m fine with it. I installed homebrew next. Homebrew requires XCode, and I knew that beforehand; what I didn&amp;#8217;t know about is that it doesn&amp;#8217;t like XCode 4.2. The App Store only has version 4.2 (and higher when you read this post at a later date). The homebrew notes has the &lt;a href='https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.1_for_lion/xcode_4.1_for_lion.dmg'&gt;link&lt;/a&gt; to version 4.1. Download and install. Here&amp;#8217;s a caveat: the dmg contains an installer. The installer installs &lt;code&gt;Install XCode.app&lt;/code&gt; in your Applications folder. You&amp;#8217;ll need to run that installer to finally get XCode installed. This confused me to no end for an hour.&lt;/p&gt;

&lt;p&gt;Git, ctags, zsh, and tmux installations were straight forward. Homebrew is your friend. Unfortunately though, homebrew does not have a vim formula (and probably does not plan to). &lt;strike&gt;I had to install this from scratch.  This is probably the
 long-winded process of getting it installed, but I digress:&lt;/strike&gt; Update: You can brew install it.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/vim.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I have been using MacVim for the past year and a half, but since this summer have been using it exclusively. I&amp;#8217;m taking a step further and switch to vim, so I can use it in tmux sessions, over ssh, etc. I used to use AkitaOnRails&amp;#8217; vimfiles, but decided to adopt this &lt;a href='https://github.com/braintreeps/vim_dotfiles'&gt;vimfiles&lt;/a&gt; instead. I&amp;#8217;m using this setup right now to write this blog post and so far I&amp;#8217;m loving it.&lt;/p&gt;

&lt;p&gt;Caveats to getting the vimfiles to work. If you&amp;#8217;re a fan of wincent&amp;#8217;s Command-T, then this may be troublesome. The plugin kept segfaulting, so I removed it completely from the bundle directory. This is even after compiling Command-T using system ruby. The vimfiles uses FuzzyFinder anyway, so it&amp;#8217;s not the end of the world.&lt;/p&gt;

&lt;p&gt;The vim that came with Lion will not work with vim plugins that need Ruby support. You can easily check this by checking the version (&lt;code&gt;vim --version&lt;/code&gt;). It should have a plus next to &lt;code&gt;ruby&lt;/code&gt;. So if FuzzyFinder is not working for you, it&amp;#8217;s because &lt;code&gt;ruby&lt;/code&gt; was not enabled for the vim you have.&lt;/p&gt;

&lt;h2 id='final_words'&gt;Final Words&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed the TL;DR post. I know I wasn&amp;#8217;t very descriptive on every step of the process, so if you have any questions, let me know in the comments.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/67VfrcgN9Vg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2011/11/13/mac-os-x-lion-development-environment</feedburner:origLink></entry>
 
 <entry>
   <title>gnu smalltalk koans</title>
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <category term="--" />
   
   <category term="koans" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/cC4n9HYar2k/gnu-smalltalk-koans" />
   <updated>2011-06-21T21:59:00-07:00</updated>
   <id>http://skim.la/2011/06/21/gnu-smalltalk-koans</id>
   <content type="html">&lt;p&gt;It&amp;#8217;s been a while since I blogged here, but I recently gave a talk, &amp;#8220;Introduction to GNU Smalltalk&amp;#8221; at &lt;a href='http://chicagocodecamp.com/sessions/114'&gt;Chicago Code Camp&lt;/a&gt; and just moments ago, &amp;#8220;GNU Smalltalk Koans&amp;#8221; at the &lt;a href='http://mchenry.softwarecraftsmanship.org/#!/introduction-to-smalltalk-by-steve-kim'&gt;Software Craftsmanship McHenry&lt;/a&gt; meetup. Yes, you read that right. A set of tests to teach you the Smalltalk language. See slides &lt;a href='http://smalltalk.heroku.com/'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Heavily inspired by &lt;a href='http://skim.la/2010/03/29/ruby-koans-is-awesome'&gt;Ruby Koans&lt;/a&gt; and &lt;a href='http://skim.la/2010/07/28/clojure-koans-is-awesome'&gt;Clojure Koans&lt;/a&gt;, &lt;a href='https://github.com/sl4m/gnu_smalltalk_koans'&gt;GNU Smalltalk Koans&lt;/a&gt; attempts to teach you the Smalltalk language, syntax, and most of the standard libraries. If you&amp;#8217;re a Rubyist and have not been exposed to Smalltalk, here&amp;#8217;s your chance to find out how much Smalltalk influenced Ruby.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;README.markdown&lt;/code&gt; should suffice in getting you started, but let&amp;#8217;s get down to the nitty gritty and reach our way to enlightenment.&lt;/p&gt;

&lt;h2 id='requirements'&gt;Requirements&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mac OS X or Linux&lt;/li&gt;

&lt;li&gt;GNU Smalltalk &lt;code&gt;3.2.2&lt;/code&gt; or higher&lt;/li&gt;

&lt;li&gt;an editor of your choice that supports Smalltalk (e.g., redcar, vim, emacs, Textmate)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Unfortunately, Windows support is not available at this time. I&amp;#8217;m unable to build it on my system, but feel free to fork the project and contribute!&lt;/p&gt;

&lt;h2 id='git_clone_project_or_download_tarballzip'&gt;Git Clone Project or Download tarball/zip&lt;/h2&gt;

&lt;p&gt;If you have git on your system, the easiest way to get the koans is to perform:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone git@github.com:sl4m/gnu_smalltalk_koans.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you don&amp;#8217;t have git, not a problem. Go to the &lt;a href='https://github.com/sl4m/gnu_smalltalk_koans/archives/master'&gt;Downloads&lt;/a&gt; section to grab your tarball or zip file and extract it to a location of your choosing.&lt;/p&gt;

&lt;h2 id='running_koans'&gt;Running Koans&lt;/h2&gt;

&lt;p&gt;Once you&amp;#8217;re ready to dive in, simply type: &lt;code&gt;script/run&lt;/code&gt; in the project root directory. You will see a message like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TestAssert#testTruth has damaged your karma.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It will tell you which file to open and which test to correct. In this case, you&amp;#8217;ll need to open &lt;code&gt;TestAssert.st&lt;/code&gt; file under &lt;code&gt;src/koans&lt;/code&gt; and correct &lt;code&gt;testTruth&lt;/code&gt; method (aka message). Once you have corrected the test, re-run &lt;code&gt;script/run&lt;/code&gt; to see what other koans might have damaged your karma. Repeat and rinse.&lt;/p&gt;

&lt;h2 id='closing'&gt;Closing&lt;/h2&gt;

&lt;p&gt;Be sure to read the rest of the &lt;code&gt;README.markdown&lt;/code&gt; as it has some important information. This is an open source project, so feel free to fork it, contribute, give feedback, I&amp;#8217;m all ears! Thanks for stopping by!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/cC4n9HYar2k" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2011/06/21/gnu-smalltalk-koans</feedburner:origLink></entry>
 
 <entry>
   <title>jasmine on rails</title>
   
   <category term="--" />
   
   <category term="javascript" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/dWyhK910wEQ/jasmine-on-rails" />
   <updated>2011-02-19T10:45:00-08:00</updated>
   <id>http://skim.la/2011/02/19/jasmine-on-rails</id>
   <content type="html">&lt;p&gt;My first 8LU (&lt;a href='http://8thlight.com/'&gt;8th Light&lt;/a&gt; University) series was on Jasmine. I learned Jasmine on a recent Rails 3 project and found it be a nice addition to the testing arsenal. There are still some quirks with the framework, but the Pivotal guys are behind it and it can be used now in any project. I look forward to using it more in future projects.&lt;/p&gt;

&lt;p&gt;The slides are online &lt;a href='http://jor.heroku.com/'&gt;here&lt;/a&gt;. The slides repo is &lt;a href='https://github.com/sl4m/jasmine_on_rails3_slides'&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/dWyhK910wEQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2011/02/19/jasmine-on-rails</feedburner:origLink></entry>
 
 <entry>
   <title>tic tac toe in smalltalk</title>
   
   <category term="--" />
   
   <category term="smalltalk" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/-XYuRtYAKdc/tic-tac-toe-in-smalltalk" />
   <updated>2010-12-03T17:30:00-08:00</updated>
   <id>http://skim.la/2010/12/03/tic-tac-toe-in-smalltalk</id>
   <content type="html">&lt;p&gt;During my &lt;a href='http://skim.cc/'&gt;apprenticeship&lt;/a&gt;, I wrote a Tic Tac Toe program in Smalltalk. Initially, I planned on using &lt;a href='http://pharo-project.org/'&gt;Pharo&lt;/a&gt;, one of the major Smalltalk implementations, but found out about &lt;a href='http://smalltalk.gnu.org/'&gt;GNU Smalltalk&lt;/a&gt; and its POSIX compatibility, and went with that instead. Unfortunately (or fortunately?), GNU Smalltalk does not give you the full experience of Smalltalk. Smalltalk is about the living environment experience, not so much about the language and its semantics. As you start reading the source code, you&amp;#8217;ll start to notice some similarities between Smalltalk and Ruby. This is because Smalltalk was a major influence to Ruby. This is one of the main reasons why I chose to write Tic Tac Toe in Smalltalk.&lt;/p&gt;

&lt;p&gt;Anyway, before I go off on talking about Smalltalk history, the source code is on my GitHub &lt;a href='https://github.com/sl4m/tic_tac_toe_smalltalk'&gt;repo&lt;/a&gt;. Here is a sample of what the code looks like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='smalltalk'&gt;&lt;span class='nc'&gt;Board&lt;/span&gt; &lt;span class='nf'&gt;subclass:&lt;/span&gt; &lt;span class='nc'&gt;ThreeByThree&lt;/span&gt; [
  &lt;span class='nc'&gt;ThreeByThree&lt;/span&gt; &lt;span class='nf'&gt;class&lt;/span&gt; &lt;span class='nf'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;new&lt;/span&gt; [
    &lt;span class='o'&gt;^&lt;/span&gt;&lt;span class='bp'&gt;super&lt;/span&gt; &lt;span class='nb'&gt;new&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
  ]

  &lt;span class='nf'&gt;ThreeByThree&lt;/span&gt; &lt;span class='nf'&gt;class&lt;/span&gt; &lt;span class='nf'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='nf'&gt;create:&lt;/span&gt; &lt;span class='nv'&gt;existingBoard&lt;/span&gt; [
    &lt;span class='o'&gt;^&lt;/span&gt;&lt;span class='bp'&gt;self&lt;/span&gt; &lt;span class='nb'&gt;new&lt;/span&gt;
          &lt;span class='nf'&gt;list:&lt;/span&gt; &lt;span class='nv'&gt;existingBoard&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
          &lt;span class='nf'&gt;yourself&lt;/span&gt;
  ]

  &lt;span class='nf'&gt;initialize&lt;/span&gt; [
    &lt;span class='bp'&gt;super&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;
    &lt;span class='nv'&gt;winningPatterns&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='ss'&gt;#((&lt;/span&gt;&lt;span class='m'&gt;1&lt;/span&gt; &lt;span class='m'&gt;2&lt;/span&gt; &lt;span class='m'&gt;3&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;4&lt;/span&gt; &lt;span class='m'&gt;5&lt;/span&gt; &lt;span class='m'&gt;6&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;7&lt;/span&gt; &lt;span class='m'&gt;8&lt;/span&gt; &lt;span class='m'&gt;9&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;1&lt;/span&gt; &lt;span class='m'&gt;4&lt;/span&gt; &lt;span class='m'&gt;7&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;2&lt;/span&gt; &lt;span class='m'&gt;5&lt;/span&gt; &lt;span class='m'&gt;8&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;3&lt;/span&gt; &lt;span class='m'&gt;6&lt;/span&gt; &lt;span class='m'&gt;9&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;1&lt;/span&gt; &lt;span class='m'&gt;5&lt;/span&gt; &lt;span class='m'&gt;9&lt;/span&gt;&lt;span class='ss'&gt;)&lt;/span&gt; &lt;span class='ss'&gt;(&lt;/span&gt;&lt;span class='m'&gt;3&lt;/span&gt; &lt;span class='m'&gt;5&lt;/span&gt; &lt;span class='m'&gt;7&lt;/span&gt;&lt;span class='ss'&gt;))&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;
    &lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='nc'&gt;Array&lt;/span&gt; &lt;span class='nf'&gt;new:&lt;/span&gt; &lt;span class='m'&gt;9&lt;/span&gt; &lt;span class='nf'&gt;withAll:&lt;/span&gt; &lt;span class='s'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;
  ]

  &lt;span class='nf'&gt;findPattern:&lt;/span&gt; &lt;span class='nv'&gt;pattern&lt;/span&gt; [
    ((&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;1&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;X&amp;#39;&lt;/span&gt; &lt;span class='nf'&gt;&amp;amp;&lt;/span&gt; (&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;2&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;X&amp;#39;&lt;/span&gt; &lt;span class='nf'&gt;&amp;amp;&lt;/span&gt; (&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;3&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;)
      &lt;span class='nb'&gt;ifTrue:&lt;/span&gt; [&lt;span class='nv'&gt;winner&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;]&lt;span class='p'&gt;.&lt;/span&gt;
    ((&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;1&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;O&amp;#39;&lt;/span&gt; &lt;span class='nf'&gt;&amp;amp;&lt;/span&gt; (&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;2&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;O&amp;#39;&lt;/span&gt; &lt;span class='nf'&gt;&amp;amp;&lt;/span&gt; (&lt;span class='nv'&gt;list&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; (&lt;span class='nv'&gt;pattern&lt;/span&gt; &lt;span class='nf'&gt;at:&lt;/span&gt; &lt;span class='m'&gt;3&lt;/span&gt;)) &lt;span class='nf'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;)
      &lt;span class='nb'&gt;ifTrue:&lt;/span&gt; [&lt;span class='nv'&gt;winner&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;]&lt;span class='p'&gt;.&lt;/span&gt;
  ]
]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/-XYuRtYAKdc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/12/03/tic-tac-toe-in-smalltalk</feedburner:origLink></entry>
 
 <entry>
   <title>redcar - my new favorite text editor</title>
   
   <category term="--" />
   
   <category term="java" />
   
   <category term="--" />
   
   <category term="editor" />
   
   <category term="--" />
   
   <category term="textmate" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/C31MVRpyWW8/redcar-my-new-favorite-text-editor" />
   <updated>2010-10-01T16:30:00-07:00</updated>
   <id>http://skim.la/2010/10/01/redcar-my-new-favorite-text-editor</id>
   <content type="html">&lt;p&gt;&lt;a href='http://redcareditor.com/'&gt;Redcar&lt;/a&gt; is a new, platform-independent, Ruby-based text editor that looks and feels like Textmate, but it&amp;#8217;s open-source and free. It&amp;#8217;s currently in alpha and there are some things that it cannot do at this time, but it&amp;#8217;s pretty stable and I use it to quickly bring up projects, something IDEs typically cannot do quickly enough. Mind you, if you have already purchased Textmate, trying out Redcar might be stepping backwards. For users who does not own Textmate or e-texteditor (for Windows), Redcar might be a nice option.&lt;/p&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;The installation is pretty straight forward. You just install the &lt;em&gt;redcar&lt;/em&gt; gem and run &lt;em&gt;redcar install&lt;/em&gt; command. Afterwards, you run &lt;em&gt;redcar&lt;/em&gt;. I&amp;#8217;m sure there&amp;#8217;s a better way to do this, but currently, I have the redcar process running on one Terminal tab and call redcar to open up different projects.&lt;/p&gt;

&lt;h2 id='it_supports_textmate_themes_and_bundles'&gt;It supports Textmate Themes and Bundles&lt;/h2&gt;

&lt;p&gt;One great benefit to using Redcar is its ability to take advantage of the Textmate themes and bundles. So it basically can open any file and display proper syntax highlighting and commands. I&amp;#8217;m also a big fan of the Sunburst theme and glad to see I do not need to create it for this editor.&lt;/p&gt;

&lt;h2 id='it_supports_plugins'&gt;It supports Plugins&lt;/h2&gt;

&lt;p&gt;Another great benefit is its extensibility. It allows the community to create plugins that other users can use. Here&amp;#8217;s a &lt;a href='http://github.com/redcar/redcar/wiki/redcar-plugins'&gt;nice list of plugins&lt;/a&gt; that people have written so far.&lt;/p&gt;

&lt;h2 id='gihub_repo_and_bug_tracking'&gt;GiHub repo and Bug tracking&lt;/h2&gt;

&lt;p&gt;If you want to contribute, go to the &lt;a href='http://github.com/redcar/redcar'&gt;GitHub repo&lt;/a&gt; and help out. You can also report bugs &lt;a href='http://redcar.lighthouseapp.com/dashboard'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='go_play_with_it'&gt;Go play with it&lt;/h2&gt;

&lt;p&gt;Try it out! Especially for Windows users who only have options like e-texteditor or IntelliJ/RubyMine, Redcar is clean, minimal, and does not get in your way.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/C31MVRpyWW8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/10/01/redcar-my-new-favorite-text-editor</feedburner:origLink></entry>
 
 <entry>
   <title>bowling kata in java</title>
   
   <category term="--" />
   
   <category term="java" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <category term="--" />
   
   <category term="kata" />
   
   <category term="--" />
   
   <category term="the" />
   
   <category term="sight" />
   
   <category term="below" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/2eqFzoKBP4Q/bowling-kata-in-java" />
   <updated>2010-09-23T23:00:00-07:00</updated>
   <id>http://skim.la/2010/09/23/bowling-kata-in-java</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; It&amp;#8217;s better to watch the video on &lt;a href='http://vimeo.com/15239027'&gt;Vimeo&amp;#8217;s website&lt;/a&gt; since Vimeo does not allow HD embedding for free users.&lt;/p&gt;

&lt;p&gt;Here is my attempt to perform &lt;a href='http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata'&gt;Uncle Bob&amp;#8217;s Bowling Kata in Java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I used IntelliJ as my IDE and music by &lt;a href='http://ghostly.com/artists/the-sight-below'&gt;The Sight Below&lt;/a&gt;. His live set can be downloaded for free &lt;a href='http://soundcloud.com/modyfier/the-sight-below-process-part-200-live-at-the-seattle-art-museum'&gt;here&lt;/a&gt;. If you don&amp;#8217;t like the music, feel free to put it on mute.&lt;/p&gt;

&lt;p&gt;I encourage you to watch the video while looking at Uncle Bob&amp;#8217;s notes in the &lt;a href='http://butunclebob.com/files/downloads/Bowling%20Game%20Kata.ppt'&gt;powerpoint presentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/bowling_kata_in_java.png' alt='Bowling Kata in Java' /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/2eqFzoKBP4Q" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/09/23/bowling-kata-in-java</feedburner:origLink></entry>
 
 <entry>
   <title>sieve of eratosthenes with rspec</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/lmCKHva66C4/sieve-of-erathosthenes-with-rspec" />
   <updated>2010-09-09T11:00:00-07:00</updated>
   <id>http://skim.la/2010/09/09/sieve-of-erathosthenes-with-rspec</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; My Sieve implementation is nowhere near as fast as the one posted &lt;a href='http://github.com/joshuaclayton/sieve'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Four months ago, I &lt;a href='http://skim.la/2010/05/09/sieve-of-eratosthenes/'&gt;wrote Sieve of Eratosthenes algorithm in Ruby&lt;/a&gt;. Today, I wanted to try it again with RSpec tests and a kata-like style. You&amp;#8217;ll notice the test is inspired by Uncle Bob&amp;#8217;s kata test for &lt;a href='http://vimeo.com/7762511'&gt;Prime Factors&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='sieve_specrb'&gt;sieve_spec.rb&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='vg'&gt;$:&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expand_path&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dirname&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='bp'&gt;__FILE__&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;spec&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;sieve&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;Sieve&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='o'&gt;[&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;19&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;19&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;23&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;19&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;23&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;29&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;19&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;23&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;29&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;13&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;17&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;19&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;23&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;29&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;31&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;37&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;41&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;43&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;47&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;53&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;59&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;61&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;67&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;71&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;73&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;79&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;83&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;89&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;97&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
  &lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;primes&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;returns prime numbers up to &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='no'&gt;Sieve&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;primes&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='sieverb'&gt;sieve.rb&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Sieve&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nc'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nf'&gt;of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
    &lt;span class='n'&gt;not_primes&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;
    &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;num&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;num&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='no'&gt;Math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sqrt&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
          &lt;span class='n'&gt;not_primes&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;num&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='n'&gt;num&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_a&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;not_primes&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/lmCKHva66C4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/09/09/sieve-of-erathosthenes-with-rspec</feedburner:origLink></entry>
 
 <entry>
   <title>rails 3 rc on windows using rubyinstaller 1.9.2</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/zFUKkUfDyMo/rails-3-rc-on-windows-using-rubyinstaller-192" />
   <updated>2010-08-21T10:00:00-07:00</updated>
   <id>http://skim.la/2010/08/21/rails-3-rc-on-windows-using-rubyinstaller-192</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; Rails 3 is now available. The instructions below should also work for the final release.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update 2:&lt;/em&gt; MySQL2 gem (starting with version 0.2.5) officially works for Windows. See &lt;a href='http://gist.github.com/635442'&gt;gist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This week the Ruby team &lt;a href='http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/367983'&gt;released&lt;/a&gt; the most anticipated Ruby version, 1.9.2, and yesterday, the RubyInstaller team &lt;a href='http://groups.google.com/group/rubyinstaller/browse_thread/thread/67902a04f12cc726#'&gt;released&lt;/a&gt; 1.9.2 for Windows. Kudos to both teams for the hard work and dedication.&lt;/p&gt;

&lt;h2 id='requirements'&gt;Requirements&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://rubyforge.org/frs/download.php/72170/rubyinstaller-1.9.2-p0.exe'&gt;RubyInstaller 1.9.2-p0&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/downloads/oneclick/rubyinstaller/DevKit-4.5.0-20100819-1536-sfx.exe'&gt;DevKit-4.5.0-20100819-1536-sfx.exe&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;SQLite3 or MySQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Installing Ruby using RubyInstaller should be straight forward. The installer automatically defaults the path to &lt;em&gt;C:\Ruby192&lt;/em&gt;. If you have used DevKit in the past, you&amp;#8217;ll notice this DevKit requires a different way to install. I highly recommend following the instructions &lt;a href='http://wiki.github.com/oneclick/rubyinstaller/development-kit'&gt;here&lt;/a&gt;. You&amp;#8217;ll need to remove the old DevKit install for other Ruby installations and install the new DevKit using the &lt;em&gt;dk.rb&lt;/em&gt; script.&lt;/p&gt;

&lt;p&gt;Install Rails 3 using the &lt;em&gt;&amp;#8211;pre&lt;/em&gt; parameter. &lt;em&gt;Update:&lt;/em&gt; &amp;#8211;pre is no longer necessary now that Rails 3 is official&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;c:\devkit&amp;gt;gem install rails --pre
Temporarily enhancing PATH to include DevKit...
Successfully installed activesupport-3.0.0.rc
Successfully installed builder-2.1.2
Successfully installed i18n-0.4.1
Successfully installed activemodel-3.0.0.rc
Successfully installed rack-1.2.1
Successfully installed rack-test-0.5.4
Successfully installed rack-mount-0.6.11
Successfully installed tzinfo-0.3.23
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.6
Successfully installed actionpack-3.0.0.rc
Successfully installed arel-0.4.0
Successfully installed activerecord-3.0.0.rc
Successfully installed activeresource-3.0.0.rc
Successfully installed mime-types-1.16
Successfully installed polyglot-0.3.1
Successfully installed treetop-1.4.8
Successfully installed mail-2.2.5
Successfully installed actionmailer-3.0.0.rc
Successfully installed thor-0.14.0
Successfully installed railties-3.0.0.rc
Successfully installed bundler-1.0.0.rc.5
Successfully installed rails-3.0.0.rc
23 gems installed
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you read my previous &lt;a href='http://skim.la/2010/02/07/rails-3-beta-on-windows-using-rubyinstaller-187-rc2/'&gt;Rails 3 post&lt;/a&gt;, we had to install a lot of the dependencies separately. The latest Rails gem seems to take care of it. Also, RubyInstaller comes with Rake, so you do not need to install it.&lt;/p&gt;

&lt;p&gt;Next up is installing SQLite or MySQL (your preference).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The official Rails blog &lt;a href='http://weblog.rubyonrails.org/2010/7/26/rails-3-0-release-candidate'&gt;mentions&lt;/a&gt; support for the MySQL2 gem which takes care of the MySQL encoding issues on Ruby 1.9.2. At the time of this writing, I could not install MySQL2 gem on my Windows box, but the gem author seems to be &lt;a href='http://github.com/brianmario/mysql2/issues#issue/8'&gt;fully aware&lt;/a&gt; of the situation. In the meantime you should be able to use &lt;a href='http://blog.mmediasys.com/2009/07/06/getting-started-with-rails-and-sqlite3/'&gt;SQLite&lt;/a&gt; or &lt;a href='http://blog.mmediasys.com/2009/07/06/getting-started-with-rails-and-mysql/'&gt;MySQL with the mysql gem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s install SQLite:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;c:\devkit&amp;gt;gem install sqlite3-ruby
Temporarily enhancing PATH to include DevKit...

=============================================================================

  You&amp;#39;ve installed the binary version of sqlite3-ruby.
  It was built using SQLite3 version 3.6.23.1.
  It&amp;#39;s recommended to use the exact same version to avoid potential issues.

  At the time of building this gem, the necessary DLL files where available
  in the following download:

  http://www.sqlite.org/sqlitedll-3_6_23_1.zip

  You can put the sqlite3.dll available in this package in your Ruby bin
  directory, for example C:\Ruby\bin

=============================================================================

Successfully installed sqlite3-ruby-1.3.1-x86-mingw32
1 gem installed
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The instructions above says to use SQLite version 3.6.23.1 and provides a link to the dll. I would also get the exe which is available &lt;a href='http://www.sqlite.org/sqlite-3_6_23_1.zip'&gt;here&lt;/a&gt;. Place sqlite3.dll and sqlite3.exe in &lt;em&gt;C:\Ruby192\bin&lt;/em&gt; or a general bin directory in the PATH (thanks for the correction, Luis!).&lt;/p&gt;

&lt;p&gt;Now let&amp;#8217;s create a new Rails app. Note, the new command to create the app:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;E:\p\rails&amp;gt;rails new rails3rc --database=sqlite3
      create
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/mailers
      create  app/models
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/rails
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Start up the local server by running this command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;E:\p\rails\rails3rc&amp;gt;rails server
=&amp;gt; Booting WEBrick
=&amp;gt; Rails 3.0.0.rc application starting in development on http://0.0.0.0:3000
=&amp;gt; Call with -d to detach
=&amp;gt; Ctrl-C to shutdown server
[2010-08-21 11:48:18] INFO  WEBrick 1.3.1
[2010-08-21 11:48:18] INFO  ruby 1.9.2 (2010-08-18) [i386-mingw32]
[2010-08-21 11:48:18] INFO  WEBrick::HTTPServer#start: pid=4296 port=3000
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now you should see that familiar &lt;strong&gt;Welcome aboard&lt;/strong&gt; page on &lt;a href='http://localhost:3000/'&gt;http://localhost:3000/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/rails3rc.jpg' alt='Rails 3 RC' /&gt;&lt;/p&gt;

&lt;p&gt;Now follow the &lt;a href='http://edgeguides.rubyonrails.org/'&gt;Rails 3 Guide&lt;/a&gt; to build yourself a Rails 3 app!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/zFUKkUfDyMo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/08/21/rails-3-rc-on-windows-using-rubyinstaller-192</feedburner:origLink></entry>
 
 <entry>
   <title>clojure koans is awesome</title>
   
   <category term="--" />
   
   <category term="clojure" />
   
   <category term="--" />
   
   <category term="koans" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/vskh4ciKjGk/clojure-koans-is-awesome" />
   <updated>2010-07-28T19:30:00-07:00</updated>
   <id>http://skim.la/2010/07/28/clojure-koans-is-awesome</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; The Clojure Koans GitHub repo &lt;a href='https://github.com/functional-koans/clojure-koans'&gt;moved&lt;/a&gt;. Instructions below have been updated.&lt;/p&gt;

&lt;p&gt;I attended my first &lt;a href='http://www.meetup.com/Chicago-Clojure/'&gt;Chicago Clojure&lt;/a&gt; meetup and 8th Light&amp;#8217;s &lt;a href='http://twitter.com/trptcolin'&gt;Colin Jones&lt;/a&gt; introduced us to Clojure Koans, a Ruby Koans inspired set of tests to teach you &lt;a href='http://clojure.org/'&gt;Clojure&lt;/a&gt;, a functional programming language. After finishing the koans that night, I have a better understanding of how Clojure syntax works. You might have heard Clojure uses a lot of parentheses - it&amp;#8217;s probably not an overstatement.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how to get started and reach your way to enlightenment.&lt;/p&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Clojure Koans is on &lt;a href='https://github.com/functional-koans/clojure-koans'&gt;GitHub&lt;/a&gt;. First let&amp;#8217;s do a &lt;em&gt;git clone&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[~/local/git] git clone https://github.com/functional-koans/clojure-koans.git
Cloning into clojure-koans...
remote: Counting objects: 487, done.
remote: Compressing objects: 100% (210/210), done.
remote: Total 487 (delta 264), reused 487 (delta 264)
Receiving objects: 100% (487/487), 60.71 KiB, done.
Resolving deltas: 100% (264/264), done.
[~/local/git] cd clojure-koans 
[master][~/local/git/clojure-koans]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;#8217;s a quick look at the directory. &lt;em&gt;Note:&lt;/em&gt; Clojure Koans is no longer a branch of Functional Koans.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/clojure-koans] ls -lah
total 64
drwxr-xr-x  10 skim  staff   340B Jan  2 12:49 ./
drwxr-xr-x  55 skim  staff   1.8K Jan  2 12:49 ../
drwxr-xr-x  13 skim  staff   442B Jan  2 12:49 .git/
-rw-r--r--   1 skim  staff    32B Jan  2 12:49 .gitignore
-rw-r--r--   1 skim  staff   3.7K Jan  2 12:49 README.md
-rw-r--r--   1 skim  staff    13K Jan  2 12:49 epl-v10.html
-rw-r--r--   1 skim  staff   504B Jan  2 12:49 ideaboard.txt
-rw-r--r--   1 skim  staff   165B Jan  2 12:49 project.clj
drwxr-xr-x  10 skim  staff   340B Jan  2 12:49 script/
drwxr-xr-x   5 skim  staff   170B Jan  2 12:49 src/
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Cool, now let&amp;#8217;s install &lt;a href='http://github.com/technomancy/leiningen'&gt;Leiningen&lt;/a&gt; (pronounced &amp;#8216;LINE-ing-en&amp;#8217;) to grab the latest Clojure jar. We&amp;#8217;ll need this jar along with JRE 1.5 or higher. Most Macs should have JRE installed by default.&lt;/p&gt;

&lt;p&gt;To install Leiningen, simply download this &lt;a href='https://github.com/technomancy/leiningen/raw/stable/bin/lein'&gt;script&lt;/a&gt;, place it in your $PATH (e.g., ~/bin) and chmod it.&lt;/p&gt;

&lt;p&gt;I placed my copy in &lt;em&gt;~/bin&lt;/em&gt; and ran chmod on it.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[~/bin] ls -lah
total 48
-rw-r--r--@ 1 skim  staff   6.0K Jun 19  2010 .DS_Store
-rwxr-xr-x  1 skim  staff   221B Jun 19  2010 ack*
-rw-r--r--@ 1 skim  staff   5.6K Jan  2 13:05 lein
-rwxr-xr-x  1 skim  staff   2.2K Jun 19  2010 mvim*
[~/bin] chmod 755 lein
[~/bin] ls -lah
total 48
-rw-r--r--@ 1 skim  staff   6.0K Jun 19  2010 .DS_Store
-rwxr-xr-x  1 skim  staff   221B Jun 19  2010 ack*
-rwxr-xr-x@ 1 skim  staff   5.6K Jan  2 13:05 lein*
-rwxr-xr-x  1 skim  staff   2.2K Jun 19  2010 mvim*
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now let&amp;#8217;s run the lein executable.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[~/bin] ./lein
Downloading Leiningen now...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 6794k  100 6794k    0     0  1780k      0  0:00:03  0:00:03 --:--:-- 2905k
Leiningen is a build tool for Clojure.

Several tasks are available:
classpath   Show the classpath of the current project.
clean       Remove compiled artifacts and jars from project.
compile     Compile Clojure source into .class files.
deps        Download all dependencies and place them in the :library-path.
help        Display a list of tasks or help for a given task.
install     Install the current project or download the project specified.
interactive Enter interactive shell for calling tasks without relaunching JVM.
jar         Package up all the project&amp;#39;s files into a jar file.
javac       Compile Java source files.
new         Create a new project skeleton.
plugin      Manage user-level plugins.
pom         Write a pom.xml file to disk for Maven interop.
repl        Start a repl session either with the current project or standalone.
run         Run a -main function with optional command-line arguments.
test        Run the project&amp;#39;s tests.
test!       Run a project&amp;#39;s tests after cleaning and fetching dependencies.
uberjar     Package up all the project&amp;#39;s files and dependencies into a jar file.
upgrade     Upgrade Leiningen to the latest stable release.
version     Print version for Leiningen and the current JVM.

Run lein help $TASK for details.
Also available: readme, tutorial, copying, sample, and news.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Excellent, we have Leiningen installed. Now let&amp;#8217;s go back to the clojure-koans directory and run &lt;em&gt;lein deps&lt;/em&gt;. This will read the &lt;em&gt;project.clj&lt;/em&gt; file to find out which dependencies it needs to install.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/clojure-koans] lein deps
Downloading: org/clojure/clojure/1.3.0-alpha3/clojure-1.3.0-alpha3.pom from central
Downloading: org/clojure/clojure/1.3.0-alpha3/clojure-1.3.0-alpha3.pom from clojure
Transferring 1K from clojure
Downloading: jline/jline/0.9.94/jline-0.9.94.pom from central
Downloading: junit/junit/3.8.1/junit-3.8.1.pom from clojure
Downloading: junit/junit/3.8.1/junit-3.8.1.pom from clojure-snapshots
Downloading: junit/junit/3.8.1/junit-3.8.1.pom from clojars
Downloading: junit/junit/3.8.1/junit-3.8.1.pom from central
Downloading: org/clojure/clojure/1.3.0-alpha3/clojure-1.3.0-alpha3.jar from central
Downloading: org/clojure/clojure/1.3.0-alpha3/clojure-1.3.0-alpha3.jar from clojure
Transferring 3528K from clojure
Downloading: jline/jline/0.9.94/jline-0.9.94.jar from central
Downloading: junit/junit/3.8.1/junit-3.8.1.jar from clojure
Downloading: junit/junit/3.8.1/junit-3.8.1.jar from clojure-snapshots
Downloading: junit/junit/3.8.1/junit-3.8.1.jar from clojars
Downloading: junit/junit/3.8.1/junit-3.8.1.jar from central
Copying 3 files to /Users/skim/local/git/clojure-koans/lib
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='running_clojure_koans'&gt;Running Clojure Koans&lt;/h2&gt;

&lt;p&gt;Ok, now I&amp;#8217;m not sure how this works exactly on Windows, but Mac and Linux, you should be able to run koans this way:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/clojure-koans] script/run

FAIL in clojure.lang.PersistentList$EmptyList@1 (equalities.clj:1)
We shall contemplate truth by testing reality, via equality.
expected: (= __ true)
  actual: (not (= nil true))
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Great! If you read through the error message, you&amp;#8217;ll see there&amp;#8217;s something wrong in the equalities.clj file. All files live in the src/koans directory. Open it up, fix the tests and re-run the previous command. For the sake of showing you an example, I fixed the first test:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/clojure-koans] cat src/koans/equalities.clj 
(meditations
  &amp;quot;We shall contemplate truth by testing reality, via equality.&amp;quot;
  (= true true)

  &amp;quot;To understand reality, we must compare our expectations against reality.&amp;quot;
  (= __ (+ 1 1))

  &amp;quot;You can test equality of many things&amp;quot;
  (= (+ 3 4) __ (+ 2 __)))

[master][~/local/git/clojure-koans] script/run                 

FAIL in clojure.lang.PersistentList$EmptyList@1 (equalities.clj:1)
To understand reality, we must compare our expectations against reality.
expected: (= __ (+ 1 1))
  actual: (not (= nil 2))
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now fix the next test and you&amp;#8217;ll be on your way to enlightenment.&lt;/p&gt;

&lt;h2 id='functionsclj'&gt;functions.clj&lt;/h2&gt;

&lt;p&gt;If you ever get to &lt;em&gt;functions.clj&lt;/em&gt;, tell me how you implemented the last one! Here&amp;#8217;s mine:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='clojure'&gt;  &lt;span class='s'&gt;&amp;quot;Higher-order functions take function arguments&amp;quot;&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;= &lt;/span&gt;&lt;span class='mi'&gt;25&lt;/span&gt; &lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='k'&gt;fn &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;n&lt;/span&gt; &lt;span class='nv'&gt;f&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;f&lt;/span&gt; &lt;span class='nv'&gt;n&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;
          &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fn &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;n&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;* &lt;/span&gt;&lt;span class='nv'&gt;n&lt;/span&gt; &lt;span class='nv'&gt;n&lt;/span&gt;&lt;span class='p'&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Have fun!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/vskh4ciKjGk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/07/28/clojure-koans-is-awesome</feedburner:origLink></entry>
 
 <entry>
   <title>first look at mongodb</title>
   
   <category term="--" />
   
   <category term="nosql" />
   
   <category term="--" />
   
   <category term="mongodb" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/n35JeUA7C0o/first-look-at-mongodb" />
   <updated>2010-07-15T19:00:00-07:00</updated>
   <id>http://skim.la/2010/07/15/first-look-at-mongodb</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s what I learned from today&amp;#8217;s experimentation with MongoDB. Kudos to &lt;a href='http://10gen.com/'&gt;10gen&lt;/a&gt; for the wonderful &lt;a href='http://www.mongodb.org/display/DOCS/Ruby+Language+Center'&gt;documentation&lt;/a&gt;. Everything I needed to know about: from installation, to how it works, to what commands to use, were all right there in the docs. There was even a &lt;a href='http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart'&gt;SQL to Mongo Mapping Chart&lt;/a&gt; that helps SQL users translate MongoDB&amp;#8217;s commands and query statements. Here&amp;#8217;s a SQL to Mongo mapping of the storage structure:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;SQL&lt;/th&gt;&lt;th&gt;MongoDB&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;database&lt;/td&gt;&lt;td&gt;database&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='even'&gt;&lt;td&gt;table&lt;/td&gt;&lt;td&gt;collection&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;row&lt;/td&gt;&lt;td&gt;document&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='even'&gt;&lt;td&gt;column&lt;/td&gt;&lt;td&gt;field&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;primary key&lt;/td&gt;&lt;td&gt;_id&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Using the mongo &lt;a href='http://rubygems.org/gems/mongo'&gt;gem&lt;/a&gt; in an irb session, I learned about the classes in MongoDB.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;MongoDB Class Name&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Mongo::Connection&lt;/td&gt;&lt;td&gt;Connection object holds a specific connection to the MongoDB server&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='even'&gt;&lt;td&gt;Mongo::DB&lt;/td&gt;&lt;td&gt;Database object holds a specific database&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Mongo::Collection&lt;/td&gt;&lt;td&gt;Collection object holds a specific collection&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='even'&gt;&lt;td&gt;Mongo::Cursor&lt;/td&gt;&lt;td&gt;Cursor object holds a set of documents from a specified query&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;BSON::OrderedHash&lt;/td&gt;&lt;td&gt;OrderedHash object holds a document&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[~] irb
ruby-1.8.7-p299 &amp;gt; require &amp;#39;rubygems&amp;#39;
ruby-1.8.7-p299 &amp;gt; require &amp;#39;mongo&amp;#39;
ruby-1.8.7-p299 &amp;gt; include Mongo
ruby-1.8.7-p299 &amp;gt; connection = Connection.new
ruby-1.8.7-p299 &amp;gt; db = connection.db(&amp;#39;test_db&amp;#39;)
ruby-1.8.7-p299 &amp;gt; collection = db.collection(&amp;#39;test_coll&amp;#39;)
ruby-1.8.7-p299 &amp;gt; collection.insert({&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;sam&amp;#39;, &amp;#39;animal&amp;#39; =&amp;gt; &amp;#39;dog&amp;#39;})
ruby-1.8.7-p299 &amp;gt; collection.insert({&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;dixie&amp;#39;, &amp;#39;animal&amp;#39; =&amp;gt; &amp;#39;cat&amp;#39;, &amp;#39;breed&amp;#39; =&amp;gt; &amp;#39;maneki neko&amp;#39;})
ruby-1.8.7-p299 &amp;gt; collection.insert({&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;dixie&amp;#39;, &amp;#39;animal&amp;#39; =&amp;gt; &amp;#39;fish&amp;#39;})
ruby-1.8.7-p299 &amp;gt; cursor = collection.find
ruby-1.8.7-p299 &amp;gt; cursor.to_a[0][&amp;quot;name&amp;quot;]
 =&amp;gt; &amp;quot;sam&amp;quot; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; I took out the return values for most of the commands in the IRB session.&lt;/p&gt;

&lt;p&gt;Once you have a collection object, there are many ways to query the collection. The basic query command is the &lt;em&gt;find&lt;/em&gt; command as shown above. Without any arguments, it returns the entire collection as a Mongo::Collection object. With arguments, you can specify which documents you want returned in a cursor (Mongo::Cursor).&lt;/p&gt;

&lt;p&gt;Find a document object with a &amp;#8216;name&amp;#8217; field, and &amp;#8216;dixie&amp;#8217; value.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby-1.8.7-p299 &amp;gt; collection.find({&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;dixie&amp;#39;})
 =&amp;gt; &amp;lt;Mongo::Cursor:0x8094bb0c namespace=&amp;#39;test_db.test_coll&amp;#39; @selector={&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;dixie&amp;quot;}&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can search using any field.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby-1.8.7-p299 &amp;gt; collection.find({&amp;#39;animal&amp;#39; =&amp;gt; &amp;#39;dog&amp;#39;})
 =&amp;gt; &amp;lt;Mongo::Cursor:0x80949488 namespace=&amp;#39;test_db.test_coll&amp;#39; @selector={&amp;quot;animal&amp;quot;=&amp;gt;&amp;quot;dog&amp;quot;}&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can search against multiple fields to get a more refined search.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby-1.8.7-p299 &amp;gt; collection.find({&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;dixie&amp;#39;, &amp;#39;animal&amp;#39; =&amp;gt; &amp;#39;fish&amp;#39;})
 =&amp;gt; &amp;lt;Mongo::Cursor:0x809414f4 namespace=&amp;#39;test_db.test_coll&amp;#39; @selector={&amp;quot;name&amp;quot;=&amp;gt;&amp;quot;dixie&amp;quot;, &amp;quot;animal&amp;quot;=&amp;gt;&amp;quot;fish&amp;quot;}&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If not searching with exact values, you can use regular expressions or &lt;a href='http://www.mongodb.org/display/DOCS/Advanced+Queries'&gt;conditional operators&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby-1.8.7-p299 &amp;gt; collection.find({&amp;#39;name&amp;#39; =&amp;gt; /^d/})
 =&amp;gt; &amp;lt;Mongo::Cursor:0x8090b048 namespace=&amp;#39;test_db.test_coll&amp;#39; @selector={&amp;quot;name&amp;quot;=&amp;gt;/^d/}&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I plan to write all of the possible moves in a 4x4 Tic Tac Toe game and export the collection as a *.bson file.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;{&amp;#39;board&amp;#39; =&amp;gt; [], &amp;#39;best_moves&amp;#39; =&amp;gt; []}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Backup to *.bson file&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[~/local/mongodb/backup] mongodump --db test_db --collection test_coll
connected to: 127.0.0.1
DATABASE: test_db	 to 	dump/test_db
	test_db.test_coll to dump/test_db/test_coll.bson
		 3 objects
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/n35JeUA7C0o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/07/15/first-look-at-mongodb</feedburner:origLink></entry>
 
 <entry>
   <title>list of rspec built-in expectations</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rspec" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/h-ReN6ocJDo/list-of-rspec-built-in-expectations" />
   <updated>2010-06-29T18:30:00-07:00</updated>
   <id>http://skim.la/2010/06/29/list-of-rspec-built-in-expectations</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s the list of RSpec Built-in expectations straight off of David Chelimsky&amp;#8217;s &lt;a href='http://www.pragprog.com/titles/achbd/the-rspec-book'&gt;RSpec&lt;/a&gt; book.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;actual.should equal(expected)
actual.should eql(expected)
actual.should == expected 

actual.should_not equal(expected)
actual.should_not eql(expected)
actual.should_not == expected

actual.should be_[predicate]
actual.should be_a_predicate
actual.should be_an_[predicate]

actual.should be_[predicate](*args)
actual.should be_a_[predicate](*args)
actual.should be_an_[predicate](*args)

actual.should_not be_[predicate]
actual.should_not be_a_[predicate]
actual.should_not be_an_[predicate]

actual.should_not be_[predicate](*args)
actual.should_not be_a_[predicate](*args)
actual.should_not be_an_[predicate](*args)

actual.should match(expected)
actual.should =~ expected

actual.should_not match(expected)
actual.should_not =~ expected

actual.should be &amp;lt; expected
actual.should be &amp;lt;= expected
actual.should be &amp;gt;= expected
actual.should be &amp;gt; expected

actual.should include(expected)
actual.should have(n).items
actual.should have_exactly(n).items
actual.should have_at_least(n).items
actual.should have_at_most(n).items

actual.should_not include(expected)
actual.should_not have(n).items
actual.should_not have_exactly(n).items

proc.should raise_error
proc.should raise_error(type)
proc.should raise_error(message)
proc.should raise_error(type, message)

proc.should_not raise_error
proc.should_not raise_error(type)
proc.should_not raise_error(message)
proc.should_not raise_error(type, message)

proc.should throw_symbol
proc.should throw_symbol(type)

proc.should_not throw_symbol
proc.should_not throw_symbol(type)

actual.should be_close(expected, delta)

actual.should_not respond_to(*messages)

actual.should satisfy { |actual| block }

actual.should_not satisfy { |actual| block }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/h-ReN6ocJDo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/29/list-of-rspec-built-in-expectations</feedburner:origLink></entry>
 
 <entry>
   <title>git branching and merging</title>
   
   <category term="--" />
   
   <category term="git" />
   
   <category term="--" />
   
   <category term="github" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/OvgkFZWWFyc/git-branching-and-merging" />
   <updated>2010-06-28T08:30:00-07:00</updated>
   <id>http://skim.la/2010/06/28/git-branching-and-merging</id>
   <content type="html">&lt;p&gt;As I aim to become better at using git, I thought I&amp;#8217;d share how to branch, then later merge the branch on a git repo. I wanted to do this for my Tic Tac Toe project because I was going to add the Limelight UI. It&amp;#8217;s actually fairly easy to branch and merge. I used &lt;a href='http://twitter.com/chacon'&gt;Scott Chacon&amp;#8217;s&lt;/a&gt; wonderful &lt;a href='http://gitref.org/'&gt;Git Reference website&lt;/a&gt; and followed his examples.&lt;/p&gt;

&lt;h2 id='listing_current_branches'&gt;Listing current branches&lt;/h2&gt;

&lt;p&gt;Note: I&amp;#8217;m using zsh and these &lt;a href='http://github.com/jferris/config_files'&gt;dot files&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To list local branches:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git branch
* master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To list remote branches:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git branch -r
  origin/HEAD -&amp;gt; origin/master
  origin/master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='create_a_new_branch_check_out_new_branch'&gt;Create a new branch, check out new branch&lt;/h2&gt;

&lt;p&gt;Here I&amp;#8217;m going to create a branch called limelight.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git branch limelight
[master][~/local/git/tic_tac_toe_ruby] git branch
  limelight
* master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You might be wondering what the asterisk next to the branch name means, in this case, the asterisk next to &amp;#8220;master&amp;#8221;. It basically tells you which branch you checked out. You might then be wondering what &amp;#8220;checked out&amp;#8221; means. When you have a branch checked out, it is the active branch you are working in. &lt;em&gt;git checkout&lt;/em&gt; command allows you to switch between the local branches available. git is smart enough to understand which folder/files are in which branch, so you do not need to create separate directories for each branch. All local branches live in the same directory! Brilliant!&lt;/p&gt;

&lt;p&gt;So to check out the new branch (limelight), simply run this command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git checkout limelight
Switched to branch &amp;#39;limelight&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You could easily kill two birds with one stone and create a branch and check it out with a single command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git checkout -b limelight
Switched to a new branch &amp;#39;limelight&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Or kill four birds with two stones: create a remote branch, create a local branch, track the local branch with a remote branch and check out the new local branch.&lt;/p&gt;

&lt;p&gt;This creates a copy of origin into a new remote branch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git push origin origin:refs/heads/limelight
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:sl4m/tic_tic_toe_ruby.git
 * [new branch]      origin/HEAD -&amp;gt; limelight

[master][~/local/git/tic_tac_toe_ruby] git branch -a
master
remotes/origin/HEAD -&amp;gt; origin/master
remotes/origin/limelight
remotes/origin/master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This creates a local branch, tracks it with the newly created remote branch, and checks it out:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git checkout --track -b limelight origin/limelight
Branch limelight set up to track remote branch limelight from origin.
Switched to a new branch &amp;#39;limelight&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Go have at it and start making changes to the new branch. Once you&amp;#8217;re finished and you want to merge your changes in this branch to, let&amp;#8217;s say, master, you&amp;#8217;ll need to use &lt;em&gt;git merge&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id='merging_a_branch_to_another'&gt;Merging a branch to another&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;git merge&lt;/em&gt; is super smart about detecting folder/file creates/deletes as well as modifications to existing folders/files. One of the only times where it may not quite understand what you want is when you make modifications of the same folder/file on both branches. You&amp;#8217;ll run into merge conflicts which you can read more about &lt;a href='http://gitref.org/branching/#merge'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To merge a branch (limelight) to another (master), check out master and run &lt;em&gt;git merge&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[limelight][~/local/git/tic_tac_toe_ruby] git checkout master
Switched to branch &amp;#39;master&amp;#39;
[master][~/local/git/tic_tac_toe_ruby] git merge limelight
Updating 2083092..b7af83b
Fast-forward
 default_scene/players/combo_box.rb     |    6 --
 default_scene/players/default_scene.rb |  107 +++++++++++++++++++++++++++++++-
 default_scene/players/menu_item.rb     |    1 +
 default_scene/players/square.rb        |   35 +++++++++--
 default_scene/props.rb                 |   34 ++++++-----
 default_scene/styles.rb                |   23 +++++--
 lib/cpu_player.rb                      |    4 +-
 lib/game.rb                            |    1 +
 lib/human_player.rb                    |    5 +-
 lib/min_max_player.rb                  |   18 +++---
 lib/std_ui.rb                          |    5 ++
 lib/tic_tac_toe.rb                     |    2 +-
 production.rb                          |   18 +++---
 spec/default_scene_spec.rb             |   95 +++++++++++++++++++++++++---
 spec/menu_item_spec.rb                 |   24 +++++++
 spec/production_spec.rb                |    7 +--
 spec/square_spec.rb                    |   38 +++++++++++
 17 files changed, 352 insertions(+), 71 deletions(-)
 delete mode 100644 default_scene/players/combo_box.rb
 create mode 100644 spec/menu_item_spec.rb
 create mode 100644 spec/square_spec.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now you should see the changes you made in the new branch in the branch you merged your changes. In this case, I see the changes I made in limelight in master.&lt;/p&gt;

&lt;p&gt;Hold your horses, we&amp;#8217;re done yet. If you run &lt;em&gt;git status&lt;/em&gt;, you&amp;#8217;ll see the merge took place locally, but not on your remote branches (see your remote repo).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git status
# On branch master
# Your branch is ahead of &amp;#39;origin/master&amp;#39; by 4 commits.
#
nothing to commit (working directory clean)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you notice above, it says &amp;#8220;your branch is ahead of &amp;#8216;origin/master&amp;#8217; by 4 commits&amp;#8221;. If you&amp;#8217;ve worked with git to where you committed multiple times, but not pushed your commits to your remote repo, you will see &amp;#8220;your branch is ahead&amp;#8221; message when running &lt;em&gt;git status&lt;/em&gt;. So we&amp;#8217;ll need to push the commits to the remote repo.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:sl4m/tic_tac_toe_ruby.git
   2083092..b7af83b  master -&amp;gt; master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now you&amp;#8217;ll see the merged changes in your remote repo.&lt;/p&gt;

&lt;h2 id='delete_a_local_branch_and_then_remote_branch'&gt;Delete a local branch and then remote branch&lt;/h2&gt;

&lt;p&gt;Finally, and optionally, you can delete your local branch if you don&amp;#8217;t need it anymore. You can also make the change reflect on your remote repo.&lt;/p&gt;

&lt;p&gt;To delete your local branch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git branch -d limelight
Deleted branch limelight (was b7af83b).
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To delete your remote branch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[master][~/local/git/tic_tac_toe_ruby] git push origin :limelight
To git@github.com:sl4m/tic_tac_toe_ruby.git
 - [deleted]         limelight
[master][~/local/git/tic_tac_toe_ruby] git branch
* master
[master][~/local/git/tic_tac_toe_ruby] git branch -r
  origin/HEAD -&amp;gt; origin/master
  origin/master
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Make sure to be in a different branch than the one you&amp;#8217;re about to delete. Otherwise, git will bark at you.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;[limelight][~/local/git/tic_tac_toe_ruby] git branch -d limelight
error: Cannot delete the branch &amp;#39;limelight&amp;#39; which you are currently on.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Hope this helped. I encourage you to start branching!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/OvgkFZWWFyc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/28/git-branching-and-merging</feedburner:origLink></entry>
 
 <entry>
   <title>jsdb - standalone javascript shell</title>
   
   <category term="--" />
   
   <category term="javascript" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/N2rTlPzXqWY/jsdb-standalone-javascript-shell" />
   <updated>2010-06-22T21:00:00-07:00</updated>
   <id>http://skim.la/2010/06/22/jsdb-standalone-javascript-shell</id>
   <content type="html">&lt;p&gt;Earlier this year I was looking for a standalone JavaScript interpreter similar to Ruby&amp;#8217;s IRB to mess around in JavaScript. &lt;a href='http://www.jsdb.org/'&gt;JSDB&lt;/a&gt;, while it stands for JavaScript for databases, can easily be used to test JavaScript code snippets. This is a shell I always have opened when working with JavaScript. For the longest time I thought it was only available for Windows, but I found out yesterday it is platform independent and can be installed and run on Mac and Linux.&lt;/p&gt;

&lt;p&gt;It uses the TraceMonkey JIT compiler with the SpiderMonkey JavaScript engine from Firefox 3.5. Since it&amp;#8217;s derived from a specific JavaScript engine, code that might otherwise work on a different engine (e.g., JScript, v8), might not exactly work on this engine. There are peculiarities between JavaScript engines that give developers headaches, so let this be a warning. Otherwise, have fun with it!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/N2rTlPzXqWY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/22/jsdb-standalone-javascript-shell</feedburner:origLink></entry>
 
 <entry>
   <title>tic tac toe in ruby - refactoring part 3</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="breakable" />
   
   <category term="toys" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/wkPZxalUJnA/tic-tac-toe-in-ruby-refactoring-part-3" />
   <updated>2010-06-18T21:00:00-07:00</updated>
   <id>http://skim.la/2010/06/18/tic-tac-toe-in-ruby-refactoring-part-3</id>
   <content type="html">&lt;p&gt;The MinMaxPlayer is complete. I had trouble with the minmax algorithm and did not include tree depth as part of the logic. Now it seems to be working and I&amp;#8217;m completely stoked. Here is the MinMaxPlayer class and its RSpec tests.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;player&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;board&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;ui&amp;#39;&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;MinMaxPlayer&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Player&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;super&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_opponent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;opponent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_opponent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;winner&lt;/span&gt;
    &lt;span class='k'&gt;when&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
    &lt;span class='k'&gt;when&lt;/span&gt; &lt;span class='n'&gt;opponent&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_best_move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;depth&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;game_over?&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='n'&gt;best_score&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;999&lt;/span&gt;
      &lt;span class='n'&gt;opponent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_opponent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;empty_squares&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get_empty_squares&lt;/span&gt;
      &lt;span class='n'&gt;empty_squares&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
        &lt;span class='n'&gt;temp_board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;temp_board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;score&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='n'&gt;get_best_move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;temp_board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;opponent&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;depth&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;best_score&lt;/span&gt;
          &lt;span class='n'&gt;best_score&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt;
          &lt;span class='vi'&gt;@best_move&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;depth&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;best_score&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;make_move&lt;/span&gt;
    &lt;span class='vi'&gt;@ui&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;display_message&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Player &amp;#39;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@piece&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39; makes a move&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get_empty_squares&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nb'&gt;rand&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;get_best_move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@piece&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='vi'&gt;@best_move&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;MinMaxPlayer RSpec tests.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expand_path&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dirname&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='bp'&gt;__FILE__&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/spec_helper&amp;quot;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;min_max_player.rb&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;board&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;ui&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;stringio&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;MinMaxPlayer&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;before&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:each&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@x&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;
    &lt;span class='vi'&gt;@o&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;
    &lt;span class='vi'&gt;@b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;
    &lt;span class='vi'&gt;@ui&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;UI&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;StringIO&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;StringIO&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;MinMaxPlayer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ui&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@ui&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should inherit from Player&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='no'&gt;MinMaxPlayer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ancestors&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;include?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;Player&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return correct opponent&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get_opponent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get_opponent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return 1 if Max is winner&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return -1 if Min is winner&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return -1 if Max is winner (from Min POV)&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return 1 if Min is winner (from Min POV)&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return 0 if no one is winner&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;evaluate_score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should make winning move&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should make winning move 2&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should make winning move 3&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should make blocking move, scenario 1&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should make winning move, scenario 3&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should not make secret losing move&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@o&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='vi'&gt;@min_max&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;make_move&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/wkPZxalUJnA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/18/tic-tac-toe-in-ruby-refactoring-part-3</feedburner:origLink></entry>
 
 <entry>
   <title>tic tac toe in ruby - refactoring part 2</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="breakable" />
   
   <category term="toys" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/CpSuj4Sw8RQ/tic-tac-toe-in-ruby-refactoring-part-2" />
   <updated>2010-06-13T21:00:00-07:00</updated>
   <id>http://skim.la/2010/06/13/tic-tac-toe-in-ruby-refactoring-part-2</id>
   <content type="html">&lt;p&gt;Over the weekend, I spent more time refactoring my Tic Tac Toe program. It now looks completely different from the &lt;a href='http://skim.la/2010/03/15/tic-tac-toe-in-ruby-and-javascript'&gt;original&lt;/a&gt; source code. I attempted to use TDD 100% of the time, and I found myself using it almost all the time. It took some time getting used to writing tests first, but once I got the hang of it, it felt comfortable. There&amp;#8217;s still a lot of work to do, but here is the main file along with some tests. You can see the rest of the source code on my GitHub &lt;a href='http://github.com/sl4m/tic_tac_toe_ruby'&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# move positions&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;#  0 | 1 | 2&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  3 | 4 | 5&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  6 | 7 | 8&lt;/span&gt;

&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;game&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;human_player&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;cpu_player&amp;#39;&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;TicTacToe&lt;/span&gt;
  &lt;span class='kp'&gt;attr_reader&lt;/span&gt; &lt;span class='ss'&gt;:std_in&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:std_out&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:player1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:player2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:game&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@std_in&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;STDIN&lt;/span&gt;
    &lt;span class='vi'&gt;@std_out&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;STDOUT&lt;/span&gt;
    &lt;span class='vi'&gt;@std_in&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
    &lt;span class='vi'&gt;@std_out&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;ask_for_player&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;player_type&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class='kp'&gt;loop&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Choose player type for &amp;#39;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39; (&amp;#39;h&amp;#39; for human or &amp;#39;c&amp;#39; for cpu) &amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;player_type&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gets&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;chomp&lt;/span&gt;
      &lt;span class='k'&gt;break&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;player_type&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;h&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='n'&gt;player_type&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;c&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;player_type&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;h&amp;#39;&lt;/span&gt;
      &lt;span class='no'&gt;HumanPlayer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@std_in&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='no'&gt;CpuPlayer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;choose_players&lt;/span&gt;
    &lt;span class='vi'&gt;@player1&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ask_for_player&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@player2&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ask_for_player&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;play&lt;/span&gt;
    &lt;span class='kp'&gt;loop&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='n'&gt;choose_players&lt;/span&gt;
      &lt;span class='vi'&gt;@game&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Game&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;player1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;player2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='vi'&gt;@game&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;play&lt;/span&gt;
      &lt;span class='n'&gt;play_again&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;
      &lt;span class='kp'&gt;loop&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
        &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Do you want to play again? (&amp;#39;y&amp;#39; or &amp;#39;n&amp;#39;) &amp;quot;&lt;/span&gt;
        &lt;span class='n'&gt;play_again&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gets&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;chomp&lt;/span&gt;
        &lt;span class='k'&gt;break&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;play_again&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;y&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='n'&gt;play_again&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;n&amp;#39;&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;break&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;play_again&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;n&amp;#39;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Thanks for playing!&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vg'&gt;$0&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='bp'&gt;__FILE__&lt;/span&gt;
  &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;play&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The RSpec tests&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# tictactoe_spec.rb&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expand_path&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dirname&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='bp'&gt;__FILE__&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/spec_helper&amp;quot;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;tictactoe&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;stringio&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;human_player&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;cpu_player&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;before&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:each&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@std_in&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;StringIO&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@std_out&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;StringIO&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@std_in&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='vi'&gt;@std_out&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should be able to create a new instance&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='nb'&gt;lambda&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should_not&lt;/span&gt; &lt;span class='n'&gt;raise_error&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should allow change to stdin&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;ttt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='no'&gt;STDIN&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vi'&gt;@std_in&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should allow change to stdout&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;ttt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='no'&gt;STDOUT&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='vi'&gt;@std_out&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;should return player&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;h&amp;quot;&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ask_for_player&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance_of?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;HumanPlayer&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;std_in&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;c&amp;quot;&lt;/span&gt;
    &lt;span class='vi'&gt;@ttt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ask_for_player&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance_of?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;CpuPlayer&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/CpSuj4Sw8RQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/13/tic-tac-toe-in-ruby-refactoring-part-2</feedburner:origLink></entry>
 
 <entry>
   <title>tic tac toe in ruby - refactoring part 1</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="breakable" />
   
   <category term="toys" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/TDrF_iLJmjQ/tic-toe-toe-in-ruby-refactoring-part-1" />
   <updated>2010-06-09T14:00:00-07:00</updated>
   <id>http://skim.la/2010/06/09/tic-toe-toe-in-ruby-refactoring-part-1</id>
   <content type="html">&lt;p&gt;One of the many refactoring techniques I can apply to my smelly Tic Tac Toe code is &lt;a href='http://en.wikipedia.org/wiki/Extract_class'&gt;Extract Class&lt;/a&gt;. One of the 8th Lighters pointed me to Martin Fowler&amp;#8217;s book &lt;a href='http://www.amazon.com/Refactoring-Improving-Design-Existing-Technology/dp/0201485672/'&gt;&amp;#8220;Refactoring&amp;#8221;&lt;/a&gt; which lists a good number of refactoring techniques. In short, Extract Class refactoring is used to extract methods from an overweight class that has lost its purpose to a new class. I used this refactoring to extract methods that had reference to the board. While it&amp;#8217;s not a significant change, it helped me understand how to use RSpec and drive the code via TDD. Here&amp;#8217;s the code. It is also on &lt;a href='http://github.com/sl4m/tic_tac_toe_ruby'&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# move positions&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;#  0 | 1 | 2&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  3 | 4 | 5&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  6 | 7 | 8&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;TicTacToe&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Patterns&lt;/span&gt;
    &lt;span class='no'&gt;Winning&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ OO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O..O.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......OO /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...... OO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/OO ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O...O... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O O....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O.. ..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......O O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.. ..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/. ..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/... OO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...OO .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
    &lt;span class='no'&gt;Blocking&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/  X . X  /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ XX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X..X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......XX /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...... XX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/XX ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X...X... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X X....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X.. ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......X X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.. ..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/. ..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/... XX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...XX .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X.. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/  XX.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X.. .. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .XX   /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X  ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..  X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..  X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
 
  &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Board&lt;/span&gt;
    &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Pattern&lt;/span&gt;
      &lt;span class='no'&gt;Won&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
        &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/OOO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...OOO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......OOO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/XXX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...XXX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......XXX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
         &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    
    &lt;span class='kp'&gt;attr_reader&lt;/span&gt; &lt;span class='ss'&gt;:board&lt;/span&gt;
    &lt;span class='kp'&gt;attr_reader&lt;/span&gt; &lt;span class='ss'&gt;:winner&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
      &lt;span class='vi'&gt;@board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[].&lt;/span&gt;&lt;span class='n'&gt;fill&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;occupied?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='n'&gt;space&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;delete_at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;insert&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;space&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;display&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;		
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;---+---+---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;---+---+---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;someone_win?&lt;/span&gt;
      &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Pattern&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Won&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;
        &lt;span class='vi'&gt;@winner&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@players&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:O&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;play&lt;/span&gt;
    &lt;span class='n'&gt;winner_flag&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;times&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
        &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;display&lt;/span&gt;
        &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;else&lt;/span&gt;
        &lt;span class='n'&gt;cpu_move&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;				
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;someone_win?&lt;/span&gt;
        &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;display&lt;/span&gt;
        &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;winner&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; is the winner!&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
        &lt;span class='n'&gt;winner_flag&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
        &lt;span class='k'&gt;break&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='ss'&gt;:O&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;winner_flag&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;display&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Game is a draw.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;	
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='kp'&gt;private&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;player_move&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Enter your move [0-8]: &amp;quot;&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;gets&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;chomp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_i&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Invalid move: &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;. Please re-enter.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;occupied?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Space is already occupied. Please re-enter.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;cpu_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_winning_pattern_move&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_blocking_pattern_move&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
        &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_first_available_move&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_winning_pattern_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt;
    &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Patterns&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Winning&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_blocking_pattern_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt;
    &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Patterns&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Blocking&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_first_available_move&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;occupied?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;index&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vg'&gt;$0&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='bp'&gt;__FILE__&lt;/span&gt;
  &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;You are X.  Please go first.&amp;quot;&lt;/span&gt;
  &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;play&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here are the tests.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# tictactoe_spec.rb&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;tictactoe&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;#valid_move?&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;returns true if move is 0-8&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;returns false if move is not 0-8&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;valid_move?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;#move&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;occupies space if move is made within valid range&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;occupied?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;does not occupy space if move is made not within range&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;occupied?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;describe&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;#someone_win?&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;it&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;returns true if it finds match from pattern set&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;someone_win?&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;should&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/TDrF_iLJmjQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/06/09/tic-toe-toe-in-ruby-refactoring-part-1</feedburner:origLink></entry>
 
 <entry>
   <title>software apprenticeship</title>
   
   <category term="--" />
   
   <category term="mentorship" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <category term="--" />
   
   <category term="software" />
   
   <category term="craftsmanship" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/GrGNag4f1og/software-apprenticeship" />
   <updated>2010-05-21T10:00:00-07:00</updated>
   <id>http://skim.la/2010/05/21/software-apprenticeship</id>
   <content type="html">&lt;p&gt;Last week, I accepted a software apprenticeship offer at &lt;a href='http://8thlight.com/'&gt;8th Light&lt;/a&gt; and will be starting next month. It&amp;#8217;s really exciting to &lt;a href='http://apprenticeship-patterns.labs.oreilly.com/ch04.html#be_the_worst'&gt;be the worst&lt;/a&gt; again and I look forward to the challenges ahead. I plan to write about my experience as a software apprentice in a different blog. If you&amp;#8217;d like, bookmark the url below.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://skim.cc/'&gt;Software Apprenticeship blog&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/GrGNag4f1og" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/05/21/software-apprenticeship</feedburner:origLink></entry>
 
 <entry>
   <title>sieve of eratosthenes</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/u5_hH8ZduZM/sieve-of-eratosthenes" />
   <updated>2010-05-09T13:00:00-07:00</updated>
   <id>http://skim.la/2010/05/09/sieve-of-eratosthenes</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; Four months later, I found a bug in my code. &lt;em&gt;if m &amp;lt; Math.sqrt(@number)&lt;/em&gt; should be &lt;em&gt;if m &amp;lt;= Math.sqrt(@number)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Last week, I learned about Sieve of Eratosthenes. According to &lt;a href='http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes'&gt;Wikipedia&lt;/a&gt;, it&amp;#8217;s an ancient algorithm created by an ancient Greek mathematician, Eratosthenes, for finding all prime numbers (below 10 million).&lt;/p&gt;

&lt;p&gt;I was asked to write the ancient algorithm in Ruby. Here is the code.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Sieve&lt;/span&gt;
  &lt;span class='kp'&gt;attr_reader&lt;/span&gt; &lt;span class='ss'&gt;:prime_numbers&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@number&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_i&lt;/span&gt;
    &lt;span class='vi'&gt;@prime_numbers&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='vi'&gt;@number&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_a&lt;/span&gt;
    &lt;span class='n'&gt;remove_non_prime_numbers&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;remove_non_prime_numbers&lt;/span&gt;
    &lt;span class='vi'&gt;@prime_numbers&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='no'&gt;Math&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sqrt&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@number&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='vi'&gt;@prime_numbers&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
            &lt;span class='vi'&gt;@prime_numbers&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;delete&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vg'&gt;$0&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='bp'&gt;__FILE__&lt;/span&gt;
  &lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Sieve&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;ARGV&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;prime_numbers&lt;/span&gt;
  &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;There are &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;length&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; prime numbers: &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/u5_hH8ZduZM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/05/09/sieve-of-eratosthenes</feedburner:origLink></entry>
 
 <entry>
   <title>ruby koans is awesome</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/NiMV83LkH3I/ruby-koans-is-awesome" />
   <updated>2010-03-29T22:00:00-07:00</updated>
   <id>http://skim.la/2010/03/29/ruby-koans-is-awesome</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The creators of Ruby Koans, Edgecase, has created a wonderful Ruby Koans website. Check it &lt;a href='http://www.rubykoans.com/'&gt;out&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/edgecase/ruby_koans'&gt;Ruby Koans&lt;/a&gt; is a set of tests to teach you the Ruby language. I&amp;#8217;m impressed how much I&amp;#8217;m learning from these tests and right off the bat, it&amp;#8217;s using Test::Unit which gives you an introduction to &lt;a href='http://en.wikipedia.org/wiki/Test-driven_development'&gt;TDD&lt;/a&gt; style coding.&lt;/p&gt;

&lt;h2 id='how_to_get_started'&gt;How to get started&lt;/h2&gt;

&lt;p&gt;The README.rdoc at Ruby Koans &lt;a href='http://github.com/edgecase/ruby_koans'&gt;GitHub repo&lt;/a&gt; should suffice, but if that wasn&amp;#8217;t clear, you should have the following already installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 1.8.6 or higher (I used 1.8.7)&lt;/li&gt;

&lt;li&gt;msysgit, Git OSX, or zip program&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically, do a git clone on the Ruby Koans repo (or download zip &lt;a href='http://github.com/downloads/edgecase/ruby_koans/rubykoans.zip'&gt;file&lt;/a&gt;):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;git clone git://github.com/edgecase/ruby_koans.git
Initialized empty Git repository in E:/p/git/fake/ruby_koans/.git/
remote: Counting objects: 294, done.
remote: Compressing objects: 100% (286/286), done.
remote: Total 294 (delta 184), reused 0 (delta 0)
Receiving objects: 100% (294/294), 51.84 KiB, done.
Resolving deltas: 100% (184/184), done.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Done. Get out your favorite editor (or IDE) and have a command prompt|shell or two ready. You want to first run &lt;em&gt;path_to_enlightenment.rb&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby path_to_enlightenment.rb

Thinking AboutAsserts
  test_assert_truth has damaged your karma.

You have not yet reached enlightenment ...
&amp;lt;false&amp;gt; is not true.

Please meditate on the following code:
./about_asserts.rb:10:in `test_assert_truth&amp;#39;
path_to_enlightenment.rb:28


mountains are merely mountains
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Open &lt;em&gt;about_asserts.rb&lt;/em&gt; and look up the test method called &lt;em&gt;test_assert_truth&lt;/em&gt; and fix whatever is wrong with it. The tests will give you hints, so don&amp;#8217;t worry, you&amp;#8217;ll figure it out. Once you do, save the file, re-run &lt;em&gt;path_to_enlightenment.rb&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ruby path_to_enlightenment.rb

Thinking AboutAsserts
  test_assert_truth has expanded your awareness.
  test_assert_with_message has damaged your karma.

You have not yet reached enlightenment ...
This should be true -- Please fix this.
&amp;lt;false&amp;gt; is not true.

Please meditate on the following code:
./about_asserts.rb:16:in `test_assert_with_message&amp;#39;
path_to_enlightenment.rb:28


learn the rules so you know how to break them properly
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You will now see that &lt;em&gt;test_assert_truth&lt;/em&gt; has expanded your awareness. Now go on to the next test and fix the problem in there. Rinse and repeat.&lt;/p&gt;

&lt;p&gt;If you ever get up to &lt;em&gt;about_scoring_project.rb&lt;/em&gt;, please let me know how you implemented the score method. Here&amp;#8217;s mine:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;dice&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;total&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
  &lt;span class='n'&gt;rolls&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;dice&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dup&lt;/span&gt;
  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;total&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;rolls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; 
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;rolls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;=&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
      &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;times&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
        &lt;span class='n'&gt;rolls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;delete_at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;rolls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;index&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='n'&gt;total&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='mi'&gt;1000&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='n'&gt;rolls&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
      &lt;span class='n'&gt;total&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;
    &lt;span class='k'&gt;elsif&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;
      &lt;span class='n'&gt;total&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;50&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='n'&gt;total&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I added additional tests just for the heck of it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_other_oddities&lt;/span&gt;
    &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='mi'&gt;1100&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='mi'&gt;1200&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='mi'&gt;600&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;#8217;s my Proxy class from &lt;em&gt;about_proxy_object_project.rb&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Proxy&lt;/span&gt;
  &lt;span class='kp'&gt;attr_reader&lt;/span&gt; &lt;span class='ss'&gt;:messages&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;target_object&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@object&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;target_object&lt;/span&gt;
    &lt;span class='vi'&gt;@messages&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;method_missing&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;method_name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;block&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@messages&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;method_name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@object&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;__send__&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;method_name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;called?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;message&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='vi'&gt;@messages&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;index&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;message&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
    &lt;span class='kp'&gt;false&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;number_of_times_called&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;message&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='vi'&gt;@messages&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;message&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Have fun!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/NiMV83LkH3I" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/03/29/ruby-koans-is-awesome</feedburner:origLink></entry>
 
 <entry>
   <title>ruby vs. javascript - quick comparison</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="javascript" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/M8NL2fFmGCQ/ruby-vs-javascript-quick-comparison" />
   <updated>2010-03-20T20:30:00-07:00</updated>
   <id>http://skim.la/2010/03/20/ruby-vs-javascript-quick-comparison</id>
   <content type="html">&lt;p&gt;These are my initial observations between the two languages so far.&lt;/p&gt;

&lt;h2 id='nil_and_null'&gt;nil and null&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;is_a?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;Object&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;# true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;JavaScript&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='k'&gt;typeof&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;object&amp;quot;&lt;/span&gt; &lt;span class='c1'&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unlike Ruby, &lt;em&gt;null&lt;/em&gt; is not derived from a class (or object), but is a special value, so it does not have any members. &lt;em&gt;typeof&lt;/em&gt; returns &amp;#8220;object&amp;#8221; for backward compatibility reasons.&lt;/p&gt;

&lt;h2 id='falsy_values'&gt;falsy values&lt;/h2&gt;

&lt;p&gt;In Ruby, zero and empty strings are considered truthy values.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;   &lt;span class='c1'&gt;# status = false&lt;/span&gt;
&lt;span class='n'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;false&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt; &lt;span class='c1'&gt;# status = false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;JavaScript&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;status&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;      &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;     &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;         &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;        &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;        &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c1'&gt;// status = false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='strings'&gt;strings&lt;/h2&gt;

&lt;p&gt;Both Ruby and JavaScript use single and double quotes for creating strings. You can also use single quotes in double quotes and vice versa without the need to escape them. However, Ruby has some powerful flexible quoting features.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%(hello world)&lt;/span&gt;  &lt;span class='c1'&gt;# &amp;quot;hello world&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%!hello world!&lt;/span&gt;  &lt;span class='c1'&gt;# &amp;quot;hello world&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;c&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%{hello world}&lt;/span&gt;  &lt;span class='c1'&gt;# &amp;quot;hello world&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%Q{hello world}&lt;/span&gt; &lt;span class='c1'&gt;# &amp;quot;hello world&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;e&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%{&lt;/span&gt;
&lt;span class='sx'&gt;hello&lt;/span&gt;
&lt;span class='sx'&gt;world&lt;/span&gt;
&lt;span class='sx'&gt;}&lt;/span&gt;                   &lt;span class='c1'&gt;# &amp;quot;\nhello\nworld\n&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ruby supports &lt;a href='http://en.wikipedia.org/wiki/Here_document'&gt;heredocs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class='no'&gt;EOS&lt;/span&gt;
&lt;span class='sh'&gt;hello&lt;/span&gt;
&lt;span class='sh'&gt;world&lt;/span&gt;
&lt;span class='no'&gt;EOS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ruby uses the shovel operator to modify original strings.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;new_string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;string&lt;/span&gt;
&lt;span class='n'&gt;new_string&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; world&amp;quot;&lt;/span&gt;  &lt;span class='c1'&gt;# &amp;quot;hello world&amp;quot; (appends &amp;#39; world&amp;#39; to new_string)&lt;/span&gt;
&lt;span class='n'&gt;string&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt; &lt;span class='c1'&gt;# true (modified original string)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ruby does not interpret escape characters when using single quotes (except itself). JavaScript always interprets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt;   &lt;span class='c1'&gt;# 1&lt;/span&gt;
&lt;span class='s1'&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt;   &lt;span class='c1'&gt;# 2&lt;/span&gt;
&lt;span class='s1'&gt;&amp;#39;\&amp;#39;&amp;#39;&lt;/span&gt;        &lt;span class='c1'&gt;# &amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;JavaScript&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='s2'&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt; &lt;span class='c1'&gt;// 1&lt;/span&gt;
&lt;span class='s1'&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt; &lt;span class='c1'&gt;// 1&lt;/span&gt;
&lt;span class='s1'&gt;&amp;#39;\&amp;#39;&amp;#39;&lt;/span&gt;        &lt;span class='c1'&gt;// &amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ruby has some other features.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;number&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;21&lt;/span&gt;
&lt;span class='n'&gt;string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Your lucky number today is &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;number&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='c1'&gt;# &amp;quot;Your lucky number today is 21&amp;quot;&lt;/span&gt;
                                                &lt;span class='c1'&gt;# (string interpolation only works for double quoted strings)&lt;/span&gt;

&lt;span class='n'&gt;string&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;  &lt;span class='c1'&gt;# &amp;#39;lucky&amp;#39; (substring)&lt;/span&gt;
&lt;span class='n'&gt;string&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='c1'&gt;# &amp;#39;lucky&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='arrays'&gt;arrays&lt;/h2&gt;

&lt;p&gt;Ruby has some really cool shorthand methods.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ruby&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;a&amp;#39;&lt;/span&gt;                  &lt;span class='c1'&gt;# shovel operator acts like JavaScript&amp;#39;s push method&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;b&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt;                    &lt;span class='c1'&gt;# 3 (Ruby also has length like JavaScript)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt;                   &lt;span class='c1'&gt;# &amp;quot;a&amp;quot; (first element)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;                    &lt;span class='c1'&gt;# &amp;quot;c&amp;quot; (last element)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;                     &lt;span class='c1'&gt;# &amp;quot;c&amp;quot; (walks backwards)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[-&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;                     &lt;span class='c1'&gt;# &amp;quot;a&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;                    &lt;span class='c1'&gt;# [&amp;quot;a&amp;quot;] (acts like JavaScript&amp;#39;s slice method)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;                    &lt;span class='c1'&gt;# [&amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;]&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;                   &lt;span class='c1'&gt;# [&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;] (between index 0 and 2, inclusive)&lt;/span&gt;
&lt;span class='n'&gt;first&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;second&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;third&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;  &lt;span class='c1'&gt;# first =&amp;gt; &amp;quot;a&amp;quot;, second =&amp;gt; &amp;quot;b&amp;quot;, third =&amp;gt; &amp;quot;c&amp;quot;&lt;/span&gt;
&lt;span class='n'&gt;another_array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sx'&gt;%w(a b c)&lt;/span&gt;     &lt;span class='c1'&gt;# [&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;] (equivalent to String#split)&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;another_array&lt;/span&gt;        &lt;span class='c1'&gt;# true&lt;/span&gt;
&lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='sx'&gt;%w(a b)&lt;/span&gt;               &lt;span class='c1'&gt;# [&amp;quot;c&amp;quot;] (returns the difference between both arrays)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='resources'&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://github.com/edgecase/ruby_koans'&gt;Ruby Koans&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://caiustheory.com/ruby-shortcuts'&gt;Ruby Shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/M8NL2fFmGCQ" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/03/20/ruby-vs-javascript-quick-comparison</feedburner:origLink></entry>
 
 <entry>
   <title>tic tac toe in ruby and javascript</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="javascript" />
   
   <category term="--" />
   
   <category term="breakable" />
   
   <category term="toys" />
   
   <category term="--" />
   
   <category term="node.js" />
   
   <category term="--" />
   
   <category term="pomodoro" />
   
   <category term="--" />
   
   <category term="tdd" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/gPOunczPbjw/tic-tac-toe-in-ruby-and-javascript" />
   <updated>2010-03-15T23:55:00-07:00</updated>
   <id>http://skim.la/2010/03/15/tic-tac-toe-in-ruby-and-javascript</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The latest Ruby source can be found &lt;a href='http://github.com/sl4m/tic_tac_toe_ruby'&gt;here&lt;/a&gt; and JavaScript source &lt;a href='http://github.com/sl4m/tic_tac_toe_js'&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='the_challenge'&gt;The Challenge&lt;/h2&gt;

&lt;p&gt;I was &amp;#8220;challenged&amp;#8221; by someone last week to build a tic tac toe game that should consist of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;human vs. computer&lt;/li&gt;

&lt;li&gt;some form of user interface (text-based is ok)&lt;/li&gt;

&lt;li&gt;computer can never lose, only draw&lt;/li&gt;

&lt;li&gt;can be written in any programming language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don&amp;#8217;t recall the last time I created a game, let alone a game with some form of AI. So what would any person like me do? Search on &lt;a href='http://google.com/'&gt;Google&lt;/a&gt; of course. I used keywords like &lt;em&gt;tic tac toe algorithm&lt;/em&gt;, &lt;em&gt;tic tac toe AI&lt;/em&gt;, and discovered different ways people solved the problem.&lt;/p&gt;

&lt;p&gt;My friend who works for Siemens, told me to use a library he uses at work called &lt;a href='http://code.google.com/p/rl-library/'&gt;rl-library&lt;/a&gt;. It is a &lt;a href='http://en.wikipedia.org/wiki/Reinforcement_learning'&gt;Reinforcement Learning&lt;/a&gt; library that is capable of &amp;#8216;learning&amp;#8217; based on user-defined environments. I found the framework to be very fascinating but I thought it would make the challenge too easy, so I had to opt out (I did add the &lt;a href='http://www.amazon.com/exec/obidos/tg/detail/-/0262193981/ref=ord_cart_shr?_encoding=UTF8&amp;amp;m=ATVPDKIKX0DER&amp;amp;v=glance'&gt;Reinforcement Learning book&lt;/a&gt; to my wish list though). I told him I wanted to avoid all external libraries and he thought about another way. For the next several hours, we sat down together via Skype, sharing his screen to show me how to develop a table of all possible moves in memory. I mean it&amp;#8217;s only 9! (or 362,880) possibilities which will consume some megabytes of memory. So by the end of the night, we had some code in Java and I needed to complete the state/action piece for this table to be useful - in other words, after the table has been created, I needed to determine which move was the best move (from the computer standpoint).&lt;/p&gt;

&lt;p&gt;I was at a loss. I think it was easy for my friend since he thinks in RL, but I couldn&amp;#8217;t figure it out right away. So off to Google I went again, looking for another solution. I found several search results and ended up finding what became my solution. I never looked at Tic Tac Toe beyond the rules and playing the game, so it was interesting to learn about the algorithm that the computer would use. This &lt;a href='http://webster.cs.ucr.edu/AsmTools/MASM/TicTacToe/ttt3_1.html'&gt;solution&lt;/a&gt; basically had a similar table, but not all 362,880 possibilities. It used pattern sets in regular expressions to look for a winning move or a blocking move. Storing these patterns in arrays of arrays, yielded the Ruby code below.&lt;/p&gt;

&lt;h2 id='tic_tac_toe_in_ruby'&gt;Tic Tac Toe in Ruby&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt; This code is old and has been replaced. See the latest &lt;a href='http://github.com/sl4m/tic_tac_toe_ruby'&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# move positions&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;#  0 | 1 | 2&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  3 | 4 | 5&lt;/span&gt;
&lt;span class='c1'&gt;# ---+---+---&lt;/span&gt;
&lt;span class='c1'&gt;#  6 | 7 | 8&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;TicTacToe&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Patterns&lt;/span&gt;
    &lt;span class='no'&gt;Winning&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ OO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O..O.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......OO /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...... OO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/OO ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O...O... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O O....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O.. ..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......O O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.. ..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/. ..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/... OO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...OO .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
    &lt;span class='no'&gt;Blocking&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/  X . X  /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ XX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X..X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......XX /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...... XX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/XX ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X...X... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X X....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X.. ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......X X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.. ..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/. ..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/... XX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...XX .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X.. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/  XX.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X.. .. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.. .XX   /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ X  ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..  X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..  X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
    &lt;span class='no'&gt;Won&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='o'&gt;[[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/OOO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...OOO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......OOO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/O...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:O&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/XXX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/...XXX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/......XXX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
       &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/X...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt; 
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[].&lt;/span&gt;&lt;span class='n'&gt;fill&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='vi'&gt;@players&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:O&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;play&lt;/span&gt;
    &lt;span class='n'&gt;winner_flag&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;times&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
        &lt;span class='nb'&gt;display&lt;/span&gt;
        &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;else&lt;/span&gt;
        &lt;span class='n'&gt;cpu_move&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;				
      &lt;span class='n'&gt;winner&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;someone_win?&lt;/span&gt;
      &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;winner&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
        &lt;span class='nb'&gt;display&lt;/span&gt;
        &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;winner&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; is the winner!&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
        &lt;span class='n'&gt;winner_flag&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
        &lt;span class='k'&gt;break&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='vi'&gt;@turn&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='ss'&gt;:O&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;winner_flag&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nb'&gt;display&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Game is a draw.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;	
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='kp'&gt;private&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;player_move&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Enter your move [0-8]: &amp;quot;&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;gets&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;chomp&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_i&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Invalid move: &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;. Please re-enter.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;
      &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;Space is already occupied. Please re-enter.&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;player_move&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;cpu_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_winning_pattern_move&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_blocking_pattern_move&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
        &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;get_first_available_move&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move&lt;/span&gt; &lt;span class='n'&gt;move_pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;delete_at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;insert&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;display&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;		
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;---+---+---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;---+---+---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; |&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;someone_win?&lt;/span&gt;
    &lt;span class='n'&gt;symbol&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt;
    &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Patterns&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Won&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;symbol&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='ss'&gt;:X&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;symbol&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;		
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_winning_pattern_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt;
    &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Patterns&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Winning&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_blocking_pattern_move&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt;
    &lt;span class='n'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Patterns&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Blocking&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='o'&gt;=~&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;array&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;get_first_available_move&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;at&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='n'&gt;move_pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@board&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;index&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;move_pos&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vg'&gt;$0&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='bp'&gt;__FILE__&lt;/span&gt;
  &lt;span class='nb'&gt;print&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n\n&lt;/span&gt;&lt;span class='s2'&gt;You are X.  Please go first.&amp;quot;&lt;/span&gt;
  &lt;span class='no'&gt;TicTacToe&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;play&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I initially began writing the game in JavaScript, but couldn&amp;#8217;t figure out a way to display the board in the console without having to deal with the browser. Luckily, I was pointed in the right direction and used &lt;a href='http://nodejs.org/'&gt;Node.js&lt;/a&gt; (sadly does not work on Windows). It handled the stdout/stdin just fine. I had to fiddle around with stdin by using Node&amp;#8217;s process object and add a listener for stdin. It wasn&amp;#8217;t immediately intuitive how the listener worked, but I was able to finally get it to prompt for user input multiple times to play the game.&lt;/p&gt;

&lt;h2 id='tic_tac_toe_in_javascript'&gt;Tic Tac Toe in JavaScript&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='cm'&gt;/**&lt;/span&gt;
&lt;span class='cm'&gt;  move positions&lt;/span&gt;

&lt;span class='cm'&gt;   0 | 1 | 2&lt;/span&gt;
&lt;span class='cm'&gt;  ---+---+---&lt;/span&gt;
&lt;span class='cm'&gt;   3 | 4 | 5&lt;/span&gt;
&lt;span class='cm'&gt;  ---+---+---&lt;/span&gt;
&lt;span class='cm'&gt;   6 | 7 | 8&lt;/span&gt;

&lt;span class='cm'&gt;*/&lt;/span&gt;

&lt;span class='nx'&gt;exports&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;sys&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;require&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;sys&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;WinningPatterns&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
    &lt;span class='p'&gt;[[(&lt;/span&gt;&lt;span class='sr'&gt;/ OO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/O..O.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......OO /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ ..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/...... OO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/OO ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ ...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/O...O... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/.. .O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/O O....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/O.. ..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......O O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..O.. ..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/. ..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/... OO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/...OO .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;]];&lt;/span&gt;
  
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;BlockingPatterns&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
    &lt;span class='p'&gt;[[(&lt;/span&gt;&lt;span class='sr'&gt;/  X . X  /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/ XX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X..X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......XX /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/...... XX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/XX ....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ ...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X...X... /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/.. .X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X X....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X.. ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......X X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..X.. ..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/. ..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/... XX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X.. ./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/...XX .../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ X X.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X.. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/.. ..X X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ X ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/  XX.. ../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X.. .. X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/.. .XX   /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/ X  ..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/ ..X..  X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/..X..  X /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;],[(&lt;/span&gt;&lt;span class='sr'&gt;/X  ..X.. /&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]];&lt;/span&gt;
       
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;WonPatterns&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
    &lt;span class='p'&gt;[[(&lt;/span&gt;&lt;span class='sr'&gt;/OOO....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/...OOO.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......OOO/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/O..O..O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/.O..O..O./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/..O..O..O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/O...O...O/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/..O.O.O../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/XXX....../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/...XXX.../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/......XXX/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/X..X..X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/.X..X..X./&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/..X..X..X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
     &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/X...X...X/&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='sr'&gt;/..X.X.X../&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]];&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[];&lt;/span&gt;
  &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;+=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;O&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;players&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;O&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
      &lt;span class='nx'&gt;turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
      
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;moveCPU&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;movePos&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;getWinningPatternMove&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;getBlockingPatternMove&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;getFirstAvailableMove&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='nx'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;movePos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;O&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;move&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;piece&lt;/span&gt; &lt;span class='o'&gt;!==&lt;/span&gt; &lt;span class='nx'&gt;turn&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='nx'&gt;pos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Number&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nx'&gt;pos&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nb'&gt;isNaN&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;splice&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;piece&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;turn&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;piece&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;?&lt;/span&gt; &lt;span class='nx'&gt;O&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;getDisplay&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;display&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
      &lt;span class='s1'&gt;&amp;#39;\n\n&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39;\n---+---+---\n&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39;\n---+---+---\n&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; |&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
      &lt;span class='s1'&gt;&amp;#39;\n\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;display&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;display&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;getDisplay&lt;/span&gt;&lt;span class='p'&gt;());&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;isBoardFilled&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;getFirstAvailableMove&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;movePos&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;display&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Game is a draw.\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stdio&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;close&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;isGameWinner&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;
        &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;WonPatterns&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;gameWinner&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;+=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;WonPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nx'&gt;gameWinner&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;WonPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;gameWinner&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;display&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;gameWinner&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; is the winner!\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stdio&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;close&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;getWinningPatternMove&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;
        &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;WinningPatterns&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;+=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;WinningPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;WinningPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;getBlockingPatternMove&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;
        &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;max&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;BlockingPatterns&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;+=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;array&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;flatBoard&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;BlockingPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;array&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;BlockingPatterns&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;getFirstAvailableMove&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;indexOf&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;play&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;display&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Enter your move [0-8]: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stdio&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;addListener&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;response&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;response&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;isGameWinner&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;isBoardFilled&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
              &lt;span class='nx'&gt;moveCPU&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
              &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;isGameWinner&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
                &lt;span class='nx'&gt;display&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
                &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Enter your move [0-8]: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
              &lt;span class='p'&gt;}&lt;/span&gt;
          &lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
          &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;\nI&amp;#39;m sorry Dave, I&amp;#39;m afraid I can&amp;#39;t do that.\n&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
          &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Enter your move [0-8]: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
      &lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stdio&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;open&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;getBoardDisplay&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;getDisplay&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;getTurn&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;turn&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;getBoard&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;board&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;slice&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;getCpuGamePiece&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;O&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;getHumanGamePiece&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;move&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;pos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;X&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Both implementations are a bit &lt;a href='http://en.wikipedia.org/wiki/Code_smell'&gt;smelly&lt;/a&gt;. With the time I had, I tried what I could to make it less smelly. I&amp;#8217;m also new to Ruby so I kind of have an excuse ;-). The JavaScript code is pretty much a straight port from the Ruby code, so it&amp;#8217;ll include some of the smells. One thing I was asked to do was to create tests along with the JavaScript code*. When thinking about the tests, it made me think how testable the JavaScript TicTacToe object really was. I ended up adding more public methods to the object to allow the tests to access certain properties of the object. Had I approached the problem test first, I think it would&amp;#8217;ve been easier to design the code.&lt;/p&gt;

&lt;p&gt;* Of course, I was doing this all wrong from the beginning. After implementing the code, I then thought about tests which is against &lt;a href='http://en.wikipedia.org/wiki/Test-driven_development'&gt;TDD&lt;/a&gt;. One of these days, I&amp;#8217;ll need to practice TDD and make it a habit.&lt;/p&gt;

&lt;h2 id='tic_tac_toe_tests_in_javascript'&gt;Tic Tac Toe Tests in JavaScript&lt;/h2&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;ticTacToe&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;require&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;./tic_tac_toe_node&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;sys&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;require&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;sys&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;assert&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;require&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;assert&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;runTest&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;description&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;test&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;  Testing... &amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;description&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;test&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;

  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;runTestSuite&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;\n[Test Suite starting...]\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;board has nine squares&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;getBoard&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;board does not have nine squares&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;cpu player is O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;getCpuGamePiece&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;cpu player is not O&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;human player is X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;getHumanGamePiece&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;human player is not X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;human player starts first&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;getTurn&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;human player is not going first&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;move human player piece within range [0-8]&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;could not move piece to position [4]&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;move human player piece outside of range (lower bound)&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;was allowed to move piece to position [-1]&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;move human player piece outside of range (upper bound)&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;9&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
          &lt;span class='s1'&gt;&amp;#39;was allowed to move piece to position [9]&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;runTest&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;move human player piece on same square&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;game&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
      &lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;assert&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;strictEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;movePlayer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='s1'&gt;&amp;#39;was allowed to move piece to same square twice&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;});&lt;/span&gt;
    &lt;span class='nx'&gt;sys&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;\n[Test Suite finished!]\n&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;

  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;runGame&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;ticTacToe&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;game&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='nx'&gt;play&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;

  &lt;span class='c1'&gt;// run tests&lt;/span&gt;
  &lt;span class='nx'&gt;runTestSuite&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

  &lt;span class='c1'&gt;// run the game&lt;/span&gt;
  &lt;span class='nx'&gt;runGame&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

&lt;span class='p'&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;#8217;re thinking why the JavaScript version of Tic Tac Toe isn&amp;#8217;t running on Node.js, it&amp;#8217;s because it needs to be &amp;#8216;required&amp;#8217; from another file due to the &lt;a href='http://nodejs.org/api.html#_modules'&gt;CommonJS module system&lt;/a&gt;. Just save the JavaScript TicTacToe code as &lt;em&gt;tic_tac_toe_node.js&lt;/em&gt; and JavaScript test code as &lt;em&gt;tic_tac_toe_node_test.js&lt;/em&gt; in the same folder, and run the test code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;node tic_tac_toe_node_test.js
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It should run the small test suite and execute the game. It&amp;#8217;s very simple, so it will end after a game. You&amp;#8217;ll have to run the test again to run multiple games.&lt;/p&gt;

&lt;h2 id='final_thoughts'&gt;Final Thoughts&lt;/h2&gt;

&lt;p&gt;It&amp;#8217;s amazing how much I&amp;#8217;ve learned from this challenge. A few things to take away from this experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practice, practice, practice!&lt;/li&gt;

&lt;li&gt;Build more breakable toys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More often than not, I read material, but never apply it right away or practice them. I need to be more hands-on and take on more challenges to apply what I&amp;#8217;ve learned. Another experiment I tried was using the &lt;a href='http://www.pomodorotechnique.com/'&gt;pomodoro technique&lt;/a&gt; using &lt;a href='https://chrome.google.com/extensions/detail/edhkjecdcakijjmlelnjjiohjmlaikhb'&gt;Chromodoro&lt;/a&gt;. By creating time-boxed sessions, I was able to focus on a single task at a time. It really helped and I will start using it for other needs.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/gPOunczPbjw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/03/15/tic-tac-toe-in-ruby-and-javascript</feedburner:origLink></entry>
 
 <entry>
   <title>how to make github and proxy play nicely with ssh</title>
   
   <category term="--" />
   
   <category term="github" />
   
   <category term="--" />
   
   <category term="proxy" />
   
   <category term="--" />
   
   <category term="ssh" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/De-ZkPo6AN0/how-to-make-github-and-proxy-play-nicely-with-ssh" />
   <updated>2010-02-22T22:00:00-08:00</updated>
   <id>http://skim.la/2010/02/22/how-to-make-github-and-proxy-play-nicely-with-ssh</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Update (06/30/2010)&lt;/em&gt;: This method may no longer work with the newer msysgit versions. Since I&amp;#8217;m no longer with the company that had a proxy implemented, I&amp;#8217;m not able to test out the setup.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: Scott Chacon recently &lt;a href='http://progit.org/2010/03/04/smart-http.html'&gt;posted&lt;/a&gt; about Smart HTTP transport which is basically the ability to perform git commands over HTTP with authentication, but unfortunately, it only works for git clients version 1.6.6 and above. &lt;a href='http://code.google.com/p/msysgit/'&gt;msysgit (Git for Windows)&lt;/a&gt; is currently on version 1.6.5.1. I will write a post about it once there&amp;#8217;s a new version of msysgit. &lt;a href='http://code.google.com/p/git-osx-installer/'&gt;Git for OS X&lt;/a&gt; has the supported clients.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://returnbooleantrue.blogspot.com/2009/06/using-github-through-draconian-proxies.html'&gt;Jeff Tchang&lt;/a&gt; does a pretty nice job explaining how to use git commands via SSH through the corporate proxy on Unix and Windows. I&amp;#8217;m just going to fill in a few missing gaps. This is a straight guide for making git work on Windows in your corporate environment.&lt;/p&gt;

&lt;h2 id='what_youll_need'&gt;What You&amp;#8217;ll Need&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://code.google.com/p/msysgit/'&gt;msysgit&lt;/a&gt; (I used 1.6.5.1)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.taiyo.co.jp/%7Egotoh/ssh/connect.exe'&gt;connect.c binary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Install msysgit with OpenSSH option (should be the last one in red). Follow these &lt;a href='http://help.github.com/msysgit-key-setup/'&gt;instructions&lt;/a&gt; (if you have not already) to generate SSH keys. If you prefer the command prompt like me (help guide uses cygwin aka Git Bash), then follow these simple instructions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open command prompt (cmd.exe)&lt;/li&gt;

&lt;li&gt;Navigate to %HOME%&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Windows\System32&amp;gt;cd %HOME%

C:\Users\skim&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Enter the following:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Users\skim&amp;gt;ssh-keygen -t rsa -C &amp;quot;email@address.com&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;where &amp;#8220;email@address.com&amp;#8221; is your own email address linked to your GitHub account.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will now prompt you for a filename, simply press &lt;em&gt;Enter&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;Now it will ask you for a passphrase. Now for the sake of simplicity, I&amp;#8217;m not going to enter a passphrase, but you should read this &lt;a href='http://help.github.com/working-with-key-passphrases/'&gt;help guide&lt;/a&gt; on why you should use a passphrase.&lt;/li&gt;

&lt;li&gt;Re-enter your passphrase (in my case, I left it empty and pressed &lt;em&gt;Enter&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Users\skim&amp;gt;ssh-keygen -t rsa -C &amp;quot;email@address.com&amp;quot;
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/skim/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/skim/.ssh/id_rsa.
Your public key has been saved in /c/Users/skim/.ssh/id_rsa.pub.
The key fingerprint is:
e8:ae:60:8f:38:c2:98:1d:6d:84:60:8c:9e:dd:47:81 email@address.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;At this point, it created two important files under %HOME%\.ssh : &lt;em&gt;id_rsa&lt;/em&gt; and &lt;em&gt;id_rsa.pub&lt;/em&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Users\skim&amp;gt;dir .ssh
 Volume in drive C has no label.
 Volume Serial Number is 4C30-D3E0

 Directory of C:\Users\skim\.ssh

02/07/2010  07:43 PM    &amp;lt;DIR&amp;gt;          .
02/07/2010  07:43 PM    &amp;lt;DIR&amp;gt;          ..
02/06/2010  11:10 PM             1,675 id_rsa
02/06/2010  11:10 PM               399 id_rsa.pub
02/07/2010  07:43 PM               407 known_hosts
               3 File(s)          2,481 bytes
               2 Dir(s)  11,605,680,128 bytes free
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The content of &lt;em&gt;id_rsa.pub&lt;/em&gt; will be used to add a public key to your &lt;a href='https://github.com/account#ssh_bucket'&gt;SSH public keys&lt;/a&gt; list on your GitHub account. This will allow you to talk to your GitHub repositories from the very computer you are using now. Make sure you have done this.&lt;/p&gt;

&lt;p&gt;The other file, &lt;em&gt;id_rsa&lt;/em&gt; will be used to allow access to your GitHub repositories via SSH/proxy.&lt;/p&gt;

&lt;p&gt;Under %HOME%\.ssh, create a new file called &lt;em&gt;config&lt;/em&gt; and add the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;ProxyCommand C:/git/bin/connect.exe -H username@proxy.example.com:443 %h %p

Host github.com
User git
Port 22
Hostname github.com
IdentityFile &amp;quot;C:\Users\skim\\.ssh\id_rsa&amp;quot;
TCPKeepAlive yes
IdentitiesOnly yes

Host ssh.github.com
User git
Port 443
Hostname ssh.github.com
IdentityFile &amp;quot;C:\Users\skim\\.ssh\id_rsa&amp;quot;
TCPKeepAlive yes
IdentitiesOnly yes
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Make sure to change the following in the above commands to match your environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Change &lt;em&gt;C:/git/bin/connect.exe&lt;/em&gt; to where you placed connect.exe. Make sure it&amp;#8217;s in PATH environment variable. It&amp;#8217;s important the slashes in the path are in fact forward slashes. This was discussed in Jeff Tchang&amp;#8217;s &lt;a href='http://returnbooleantrue.blogspot.com/2009/06/using-github-through-draconian-proxies.html'&gt;article&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Change &lt;em&gt;username@proxy.example.com:443&lt;/em&gt; to your proxy address. If you don&amp;#8217;t require username/password just enter the address (e.g., &lt;em&gt;proxy.example.com:443&lt;/em&gt;). Make sure the port is the port number of your corporate environment&amp;#8217;s proxy. It doesn&amp;#8217;t have to be 443.&lt;/li&gt;

&lt;li&gt;Change both &lt;em&gt;C:\Users\skim\.ssh\id_rsa&lt;/em&gt; paths to your specific %HOME%\.ssh\id_rsa path. It&amp;#8217;s important the path contains &lt;em&gt;id_rsa&lt;/em&gt; and not &lt;em&gt;id_rsa.pub&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='testing_it_out'&gt;Testing It Out&lt;/h2&gt;

&lt;p&gt;Assuming _Your_Git_Path_\bin\ folder is in your PATH environment variable, try running the following command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Users\skim&amp;gt;ssh -F %HOME%\skim\.ssh\config github.com

ERROR: Hi sl4m! You&amp;#39;ve successfully authenticated, but GitHub does not provide shell access

Connection to github.com closed.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The error is expected since GitHub does not allow shell access. What is most important is that you see the &amp;#8220;successfully authenticated&amp;#8221; message.&lt;/p&gt;

&lt;p&gt;Now that you&amp;#8217;re all set, you can run git commands. It&amp;#8217;s slightly different from the git commands you might be used to (if you&amp;#8217;re familiar with git already). When you clone a repository, you typically invoke this command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;git clone git://github.com/rails/rails.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But with SSH, this is how you invoke the same command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;git clone ssh://git@github.com:443/rails/rails.git
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Follow the pattern and you should be able to run all git commands via SSH/proxy.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/De-ZkPo6AN0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/22/how-to-make-github-and-proxy-play-nicely-with-ssh</feedburner:origLink></entry>
 
 <entry>
   <title>my rails mentor project - the beginning</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <category term="--" />
   
   <category term="github" />
   
   <category term="--" />
   
   <category term="mentorship" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <category term="project" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/XZ6Cx8bNN7k/my-rails-mentor-project-the-beginning" />
   <updated>2010-02-18T18:30:00-08:00</updated>
   <id>http://skim.la/2010/02/18/my-rails-mentor-project-the-beginning</id>
   <content type="html">&lt;p&gt;I mentioned in my previous &lt;a href='/2010/02/17/my-learning-resources/'&gt;post&lt;/a&gt; that I requested a mentorship with &lt;a href='http://www.railsmentors.org/users/237'&gt;Kris&lt;/a&gt; at &lt;a href='http://railsmentors.org/'&gt;Rails Mentors&lt;/a&gt;. I was fortunate he accepted my request and I spoke to him over the weekend via Skype to discuss about what I want to get out of this mentorship. I told him I wanted to start a small Rails project, specifically, build a website that can create rss feeds for rss-less websites. Kris liked the idea and created a &lt;a href='https://github.com/kris/mentor-sl4m'&gt;private&lt;/a&gt; github repo. He sent me his environment.rb file and my job is to look into the gems he likes to use in his Rails projects.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Be sure to restart your server when you modify this file&lt;/span&gt;

&lt;span class='c1'&gt;# Specifies gem version of Rails to use when vendor/rails is not present&lt;/span&gt;
&lt;span class='no'&gt;RAILS_GEM_VERSION&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;2.3.5&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;defined?&lt;/span&gt; &lt;span class='no'&gt;RAILS_GEM_VERSION&lt;/span&gt;

&lt;span class='c1'&gt;# Bootstrap the Rails environment, frameworks, and default configuration&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dirname&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='bp'&gt;__FILE__&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;boot&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='no'&gt;Rails&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Initializer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='c1'&gt;# Settings in config/environments/* take precedence over those specified here.&lt;/span&gt;
  &lt;span class='c1'&gt;# Application configuration should go into files in config/initializers&lt;/span&gt;
  &lt;span class='c1'&gt;# -- all .rb files in that directory are automatically loaded.&lt;/span&gt;

  &lt;span class='c1'&gt;# Add additional load paths for your own custom dirs&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;load_paths&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='sx'&gt;%W(Rails.root.join(&amp;#39;app&amp;#39;, &amp;#39;middleware&amp;#39;))&lt;/span&gt;

  &lt;span class='c1'&gt;# Specify gems that this application depends on and have them installed with rake gems:install&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;acl9&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;redis&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;redis-store&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;xapit&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;gravtastic&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;paperclip&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;stringex&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;email_veracity&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;state_machine&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;acts_as_tree&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;formtastic&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;authlogic&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;searchlogic&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;settingslogic&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;hoptoad_notifier&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;sitemap_generator&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;validates_timeliness&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;inherited_resources&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;acts-as-taggable-on&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;will_paginate&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;bullet&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;factory_girl&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;rspec&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lib&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;rspec-rails&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lib&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;webrat&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;cucumber&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gemcutter.org&amp;#39;&lt;/span&gt;

  &lt;span class='c1'&gt;# Only load the plugins named here, in the order given (default is alphabetical).&lt;/span&gt;
  &lt;span class='c1'&gt;# :all can be used as a placeholder for all plugins not explicitly named&lt;/span&gt;
  &lt;span class='c1'&gt;# config.plugins = [ :exception_notification, :ssl_requirement, :all ]&lt;/span&gt;

  &lt;span class='c1'&gt;# Skip frameworks you&amp;#39;re not going to use. To use Rails without a database,&lt;/span&gt;
  &lt;span class='c1'&gt;# you must remove the Active Record framework.&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;frameworks&lt;/span&gt; &lt;span class='o'&gt;-=&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='ss'&gt;:active_resource&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;

  &lt;span class='c1'&gt;# Activate observers that should always be running&lt;/span&gt;
  &lt;span class='c1'&gt;# config.active_record.observers = :cacher, :garbage_collector, :forum_observer&lt;/span&gt;

  &lt;span class='c1'&gt;# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.&lt;/span&gt;
  &lt;span class='c1'&gt;# Run &amp;quot;rake -D time&amp;quot; for a list of tasks for finding time zone names.&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;time_zone&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;UTC&amp;#39;&lt;/span&gt;

  &lt;span class='c1'&gt;# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.&lt;/span&gt;
  &lt;span class='c1'&gt;# config.i18n.load_path += Dir[Rails.root.join(&amp;#39;my&amp;#39;, &amp;#39;locales&amp;#39;, &amp;#39;*.{rb,yml}&amp;#39;)]&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;i18n&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;default_locale&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='ss'&gt;:en&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/XZ6Cx8bNN7k" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/18/my-rails-mentor-project-the-beginning</feedburner:origLink></entry>
 
 <entry>
   <title>my learning resources</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <category term="--" />
   
   <category term="github" />
   
   <category term="--" />
   
   <category term="continuous" />
   
   <category term="learning" />
   
   <category term="--" />
   
   <category term="mentorship" />
   
   <category term="--" />
   
   <category term="software" />
   
   <category term="craftsmanship" />
   
   <category term="--" />
   
   <category term="books" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/Xjc0hEkifkA/my-learning-resources" />
   <updated>2010-02-17T18:30:00-08:00</updated>
   <id>http://skim.la/2010/02/17/my-learning-resources</id>
   <content type="html">&lt;p&gt;There is no &lt;em&gt;/ one | right /&lt;/em&gt; way about learning. I&amp;#8217;ve looked around the net and found these along the way:&lt;/p&gt;

&lt;h2 id='ruby'&gt;Ruby&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Books&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Free e-books available online:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.humblelittlerubybook.com/'&gt;Mr. Neighborly&amp;#8217;s Humble Little Ruby Book&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/Why%27s_%28poignant%29_Guide_to_Ruby'&gt;Why&amp;#8217;s (Poignant) Guide to Ruby&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.sapphiresteel.com/The-Little-Book-Of-Ruby'&gt;The Little Book of Ruby&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, all of these are somewhat outdated. So I chose the recently published book called &lt;a href='http://www.amazon.com/Well-Grounded-Rubyist-David-Black/dp/1933988657'&gt;&amp;#8220;The Well Grounded Rubyist&amp;#8221;&lt;/a&gt; by David A. Black. I&amp;#8217;m not too far into it yet, but it was highly recommended and so far it&amp;#8217;s been very helpful. It covers Ruby 1.9.1.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s not forget Prag Prog&amp;#8217;s PickAxe, &lt;a href='http://pragprog.com/titles/ruby3/programming-ruby-1-9'&gt;&amp;#8220;Programming Ruby 1.9&amp;#8221;&lt;/a&gt; which also covers Ruby 1.9.1. This is the complete reference, so it&amp;#8217;s nice to have by your side if you need to look up a class or two.&lt;/p&gt;

&lt;p&gt;Gregory T. Brown is slowly releasing his book, &lt;a href='http://rubybestpractices.com/'&gt;&amp;#8220;Ruby Best Practices&amp;#8221;&lt;/a&gt; in digital form chapter by chapter for free. He already released four chapters and you can grab them &lt;a href='http://blog.rubybestpractices.com/'&gt;here&lt;/a&gt;. If you like what you see so far, I highly suggest picking up the dead tree version available at &lt;a href='http://oreilly.com/catalog/9780596523008/index.html'&gt;O&amp;#8217;Reilly&lt;/a&gt;, &lt;a href='http://www.amazon.com/Ruby-Best-Practices-Gregory-Brown/dp/0596523009'&gt;Amazon&lt;/a&gt;, or your local bookstore.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Courses&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is a free online Ruby course from &lt;a href='http://www.rubylearning.org/class/'&gt;RubyLearning&lt;/a&gt; which I highly recommend. Although, I have not yet completed the course, the latest course covers Ruby 1.9.1, and there are a lot of mentors willing to help in the course forum.&lt;/p&gt;

&lt;p&gt;This is not really an online course, but a self-teaching set of tests called &lt;a href='http://github.com/edgecase/ruby_koans/'&gt;Ruby Koans&lt;/a&gt;. Follow the instructions and it will guide you to the path of enlightenment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Resources&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.ruby-lang.org/en/'&gt;Official Ruby website&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ruby-lang.org/en/community/mailing-lists/'&gt;Official Ruby mailing lists&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://tryruby.org/'&gt;Try Ruby!&lt;/a&gt; (15 minute interactive tutorial)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://blog.mmediasys.com/'&gt;Luis Lavena&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://groups.google.com/group/rubyinstaller'&gt;RubyInstaller for Windows&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://vgoff.blogspot.com/'&gt;ashbb&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://rubytu.be/'&gt;RubyTu.be&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='rails'&gt;Rails&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Books&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Rails changes rapidly, so spending money on a dead-tree version of a book is probably not the best way to go. In any case, Prag Prog&amp;#8217;s &amp;#8220;Agile Web Development with Rails, Third Edition&amp;#8221; is the latest book on Rails. Unfortunately it does not contain Rails 3.0, but this ongoing &lt;a href='http://www.pragprog.com/wikis/wiki/ChangesInRails30'&gt;wiki page&lt;/a&gt; contains information about the beta and about Rails Fourth Edition.&lt;/p&gt;

&lt;p&gt;O&amp;#8217;Reilly recently announced the &lt;a href='http://broadcast.oreilly.com/2010/02/a-live-edition-for-learning-ra.html'&gt;Live Edition of Learning Rails&lt;/a&gt; which will include Rails 3.x content.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s also a Rails 3 Upgrade Handbook by Jeremy McAnally coming out soon. Sign up &lt;a href='http://spreadsheets.google.com/viewform?formkey=dEVNNjJLSlMzNzBGcEVQWERFY0N4bGc6MA'&gt;here&lt;/a&gt; to be notified when it&amp;#8217;s available. &lt;em&gt;Update:&lt;/em&gt; it&amp;#8217;s out &lt;a href='http://www.railsupgradehandbook.com/'&gt;now&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Courses&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I started using &lt;a href='http://www.buildingwebapps.com/learningrails'&gt;Learning Rails&lt;/a&gt;, a free online Ruby on Rails course. Although, it&amp;#8217;s based on an older version of Rails, the overall information about Rails is there, especially about Model-View-Controller, scaffold, migrations, rake commands, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Resources&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://rubyonrails.org/'&gt;Official Ruby on Rails website&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://rubyonrails.org/community'&gt;Official Rails community&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.akitaonrails.com/english'&gt;Akita On Rails&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://railscasts.com/'&gt;Railscasts&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://guides.rubyonrails.org/'&gt;Ruby on Rails guides&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://railsbridge.org/'&gt;Rails Bridge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Mentorship&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Probably the best move I&amp;#8217;ve made is finding a Ruby on Rails mentor at &lt;a href='http://railsmentors.org/'&gt;Rails Mentors&lt;/a&gt;. Los Angeles-based Rails developer, &lt;a href='http://twitter.com/mrkris'&gt;@kris&lt;/a&gt;, accepted my mentorship. We spoke this past weekend via Skype and will start on a project that will create custom feeds for RSS-less websites. It&amp;#8217;s a private github repo as of now and we may open it up in the future, but for now, I will blog about the project here. I&amp;#8217;m pretty excited to start this project and will hopefully learn a lot from it.&lt;/p&gt;

&lt;h2 id='metaprogramming'&gt;Metaprogramming&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Books&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Prag Prog&amp;#8217;s &lt;a href='http://pragprog.com/titles/ppmetr/metaprogramming-ruby'&gt;Metaprogramming Ruby&lt;/a&gt; book by Paolo Perotta just released this month. I have this book on my wishlist and plan to pick it up when I learn about the advanced DSL concepts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Courses&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.rubylearning.org/class/'&gt;RubyLearning&lt;/a&gt; is offering an online course on Ruby Metaprogramming on March 6th. For a small fee of $5-9, you will learn about Ruby&amp;#8217;s advanced features and start &amp;#8220;thinking in Ruby&amp;#8221;. Best part of all, Paolo Perotta will be answering some of the questions in the course forum. How cool is that? You can learn more about the course &lt;a href='http://rubylearning.com/blog/2010/02/09/ruby-metaprogramming-course-start-thinking-in-ruby/'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Resources&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://ruby-metaprogramming.rubylearning.com/'&gt;Ruby Metaprogramming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='software_craftsmanship'&gt;Software Craftsmanship&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Books&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I still have much to learn in this area. To start off, however, I recommend starting from the beginning and pick up, &lt;a href='http://oreilly.com/catalog/9780596518387'&gt;&amp;#8220;Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman&amp;#8221;&lt;/a&gt; by &lt;a href='http://twitter.com/redsquirrel'&gt;Dave Hoover&lt;/a&gt; and &lt;a href='http://twitter.com/ade_oshineye'&gt;Adewale Oshineye&lt;/a&gt;. Then there is &lt;a href='http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/'&gt;&amp;#8220;The Pragmatic Programmer&amp;#8221;&lt;/a&gt; by Andrew Hunt and Dave Thomas (Prag Dave) and the well known &lt;a href='http://www.amazon.com/Software-Craftsmanship-Imperative-Pete-McBreen/dp/0201733862/'&gt;&amp;#8220;Software Craftsmanship&amp;#8221;&lt;/a&gt; by Pete McBreen.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Online Resources&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://apprenticeship-patterns.labs.oreilly.com/'&gt;Apprenticeship Patterns wiki&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://manifesto.softwarecraftsmanship.org/'&gt;Software Craftsmanship Manifesto&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://groups.google.com/group/software_craftsmanship'&gt;Software Craftsmanship Google Group&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://wiki.softwarecraftsmanship.org/doku.php'&gt;Software Craftsmanship Wiki&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://softwarecraftsmanship.libsyn.com/'&gt;Software Craftsmanship Podcast&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Active Apprenticeship Programs&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.obtiva.com/careers/software-apprentice/'&gt;Obtiva&lt;/a&gt; (Chicago, IL)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.8thlight.com/main/about_description?sub_action=apprenticeship'&gt;8th Light&lt;/a&gt; (Libertyville, IL)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://edendevelopment.co.uk/craftsmen'&gt;Eden Development&lt;/a&gt; (Winchester, UK)&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/Xjc0hEkifkA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/17/my-learning-resources</feedburner:origLink></entry>
 
 <entry>
   <title>conference week</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <category term="--" />
   
   <category term="conference" />
   
   <category term="--" />
   
   <category term="training" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/AgQcwQNw4FI/conference-week" />
   <updated>2010-02-16T21:15:00-08:00</updated>
   <id>http://skim.la/2010/02/16/conference-week</id>
   <content type="html">&lt;p&gt;This week will be a busy week of information overload - a week of Ruby and Rails conferences. This Thursday, the free &lt;a href='http://en.oreilly.com/railswinter10'&gt;Rails Online Conference&lt;/a&gt; will exclusively be about the upcoming version of Rails. Currently, it is in its beta state and will be officially available soon. I look forward to the talks and to learn more about the new features in Rails 3.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://larubyconf.com/'&gt;LA Ruby Conference 2010&lt;/a&gt; will be on Saturday and the complementary workshops will be held on Friday. I signed up for both Ruby Koans and Intro to Ruby on Rails workshops which I&amp;#8217;m both pretty excited about. Jim Weirich and Joe O&amp;#8217;Brien will give the Ruby Koans workshop, and Alf Mikula (LA Ruby meetup organizer) will give the Intro to Ruby on Rails workshop.&lt;/p&gt;

&lt;p&gt;Here are the talks I&amp;#8217;m particularly interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://larubyconf.com/presentations/2'&gt;Oh S***: How to bring a big Rails website down (and how not to)&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://larubyconf.com/presentations/3'&gt;Alternative Data Structures in Ruby&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://larubyconf.com/presentations/5'&gt;Everything you ever wanted to know about threads and fibers, but were afraid to ask&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://larubyconf.com/presentations/9'&gt;Garbage Collection and the Ruby Heap&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://larubyconf.com/presentations/10'&gt;A New Look at Software Development: What will the next 10 years bring?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I look forward to meeting more Rubyists.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/AgQcwQNw4FI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/16/conference-week</feedburner:origLink></entry>
 
 <entry>
   <title>how to run jekyll's pygmentize on windows</title>
   
   <category term="--" />
   
   <category term="jekyll" />
   
   <category term="--" />
   
   <category term="github" />
   
   <category term="--" />
   
   <category term="pygmentize" />
   
   <category term="--" />
   
   <category term="python" />
   
   <category term="--" />
   
   <category term="windows" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/jpUMZA0gGVw/how-to-run-jekyll-pygmentize-on-windows" />
   <updated>2010-02-14T14:00:00-08:00</updated>
   <id>http://skim.la/2010/02/14/how-to-run-jekyll-pygmentize-on-windows</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Updated 06/14/2010&lt;/em&gt; &amp;#8211; This is a quick patch created by &lt;a href='http://github.com/jonforums'&gt;Jon&lt;/a&gt; at &lt;a href='http://groups.google.com/group/rubyinstaller/t/400ecfe5d528b558'&gt;RubyInstaller Google Group&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='what_you_need'&gt;What You Need&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Any &lt;a href='http://rubyinstaller.org/download.html'&gt;RubyInstaller MinGW version&lt;/a&gt; or &lt;a href='http://www.ruby-lang.org/en/downloads/'&gt;1.8.7/1.9.1 mswin32&lt;/a&gt; (Not tested using One-Click Installer)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://gemcutter.org/gems/jekyll'&gt;jekyll gem&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.python.org/download/'&gt;Python&lt;/a&gt; 2.3 or higher (I used 2.6.5)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pypi.python.org/pypi/setuptools'&gt;setuptools 0.6c11&lt;/a&gt; for easy_install&lt;/li&gt;

&lt;li&gt;&lt;a href='http://pygments.org/'&gt;pygments&lt;/a&gt; (install with easy_install)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Installing Ruby, jekyll, and Python should be self explanatory. I installed RubyInstaller 1.8.7 to C:\Ruby187\ and Python 2.6.5 to C:\Python26\.&lt;/p&gt;

&lt;p&gt;Modify the code in albino.rb and highlight.rb from C:\Ruby187\lib\ruby\gems\1.8\gems\jekyll-0.5.7\lib\jekyll\ using the following gists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://gist.github.com/304185'&gt;albino.rb&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://gist.github.com/304187'&gt;highlight.rb (under tags folder)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be sure not to just replace the entire code, just the portions of the code. If you&amp;#8217;re using Ruby 1.9.1 or your Ruby path is different, drill down to the corresponding path.&lt;/p&gt;

&lt;p&gt;I created a folder called &amp;#8216;Scripts&amp;#8217; under C:\Python26. I added C:\Python26 and C:\Python26\Scripts to the PATH environment variable.&lt;/p&gt;

&lt;p&gt;In order to install pygments, you need to install easy_install which is included in setuptools. Download the source (&lt;a href='http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefe74e'&gt;setuptools-0.6c11.tar.gz&lt;/a&gt;) and egg (&lt;a href='http://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg#md5=bfa92100bd772d5a213eedd356d64086'&gt;setuptools-0.6c11-py2.6.egg&lt;/a&gt;). Extract ez_setup.py from setuptools-0.6.c11.tar.gz to the same folder as setuptools-0.6c11-py2.6.egg. Open up a command prompt, navigate to the folder with the egg file and run:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;python ez_setup.py setuptools-0.6c11-py2.6.egg
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will add easy_install.exe and other files to your C:\Python26\Scripts folder.&lt;/p&gt;

&lt;p&gt;Now to install pygments, simply run this command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;easy_install Pygments
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;According to Jon, easy_install does not create a wrapper for the Pygmentize script, so creating a batch file pygmentize.bat under C:\Python26\Scripts should do the trick. Add this command to the batch file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;@python.exe %~dp0pygmentize %*
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now when running jekyll locally, you should be able to see the pygmentize highlights&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/jekyll_pygmentize.jpg' alt='pygmentize on windows' /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/jpUMZA0gGVw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/14/how-to-run-jekyll-pygmentize-on-windows</feedburner:origLink></entry>
 
 <entry>
   <title>update rss feed</title>
   
   <category term="--" />
   
   <category term="rss" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/3txHTHDUpak/update-rss-feed" />
   <updated>2010-02-14T12:15:00-08:00</updated>
   <id>http://skim.la/2010/02/14/update-rss-feed</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve updated the rss feed to use FeedBurner.&lt;/p&gt;

&lt;p&gt;Please point to the new feed : &lt;a href='http://feeds.feedburner.com/sl4m'&gt;http://feeds.feedburner.com/sl4m&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/3txHTHDUpak" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/14/update-rss-feed</feedburner:origLink></entry>
 
 <entry>
   <title>software testing club magazine</title>
   
   <category term="--" />
   
   <category term="testing" />
   
   <category term="--" />
   
   <category term="magazine" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/8lOK0hfgUBo/software-testing-club-magazine" />
   <updated>2010-02-08T18:30:00-08:00</updated>
   <id>http://skim.la/2010/02/08/software-testing-club-magazine</id>
   <content type="html">&lt;p&gt;I was one of the lucky ones to contribute to The Software Testing Club&amp;#8217;s first &lt;a href='http://wiki.softwaretestingclub.com/The+Software+Testing+Club+Magazine+-+No+1'&gt;magazine&lt;/a&gt; that released today for free. In it, you will find a small Twitter conversation I had with &lt;a href='http://twitter.com/QualityFrog/'&gt;@QualityFrog&lt;/a&gt; as well as a Google Wave conversation I had with &lt;a href='http://twitter.com/Rob_Lambert/'&gt;@Rob_Lambert&lt;/a&gt; and &lt;a href='http://twitter.com/YorkyAbroad/'&gt;@YorkyAbroad&lt;/a&gt;. I look forward to future contributions to this wonderful magazine. Be sure to check out the bottom-left hand corner every other page to find humorous quotes.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/8lOK0hfgUBo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/08/software-testing-club-magazine</feedburner:origLink></entry>
 
 <entry>
   <title>rails 3 beta on windows using rubyinstaller 1.8.7 rc2</title>
   
   <category term="--" />
   
   <category term="ruby" />
   
   <category term="--" />
   
   <category term="rails" />
   
   <category term="--" />
   
   <category term="windows" />
   
   <category term="--" />
   
   <category term="rubyinstaller" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/iLJ7CWJzC1Q/rails-3-beta-on-windows-using-rubyinstaller-187-rc2" />
   <updated>2010-02-07T19:15:00-08:00</updated>
   <id>http://skim.la/2010/02/07/rails-3-beta-on-windows-using-rubyinstaller-187-rc2</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; I have posted an update using Rails 3 RC and Ruby 1.9.2 &lt;a href='http://skim.la/2010/08/21/rails-3-rc-on-windows-using-rubyinstaller-192'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yesterday, I upgraded my Vista x64 machine to Windows 7 x64, so I needed to set up my Ruby/Rails environment again. As done previously, I followed information on AkitaOnRails&amp;#8217; blog post, &lt;a href='http://akitaonrails.com/2009/1/13/the-best-environment-for-rails-on-windows'&gt;The Best Environment for Rails on Windows&lt;/a&gt; to install the latest &lt;a href='http://code.google.com/p/msysgit/'&gt;msysgit&lt;/a&gt;, Exuberant CTags, &lt;a href='http://www.vim.org/index.php'&gt;gvim&lt;/a&gt;, and &lt;a href='http://akitaonrails.com/2009/04/27/the-best-environment-for-rails-on-windows-part-2'&gt;vimfiles&lt;/a&gt;, replacing the deprecated One-Click Ruby Installer with the new &lt;a href='http://rubyforge.org/frs/?group_id=167&amp;amp;release_id=42563'&gt;RubyInstaller 1.8.7 RC2&lt;/a&gt; that officially came out today.&lt;/p&gt;

&lt;h2 id='requirements'&gt;Requirements&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://rubyforge.org/frs/download.php/69034/rubyinstaller-1.8.7-p249-rc2.exe'&gt;RubyInstaller 1.8.7 RC2&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://rubyforge.org/frs/download.php/66888/devkit-3.4.5r3-20091110.7z'&gt;DevKit 3.4.5r3-20091110&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.7-zip.org/download.html'&gt;7-zip&lt;/a&gt; or zip program to uninstall 7z extensions&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.sqlite.org/sqlitedll-3_6_22.zip'&gt;SQLite3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;I chose C:\Ruby187\ as my default path and applied DevKit on top of it. Be sure to follow the instructions in INSTALL.txt in the DevKit archive. I placed sqlite3.dll in C:\Ruby187\bin.&lt;/p&gt;

&lt;p&gt;I followed the instructions on Matt Hulse&amp;#8217;s post, &lt;a href='http://matt-hulse.com/articles/2010/02/05/massaging-rails-3-beta-on-windows/'&gt;Massaging Rails 3 Beta on Windows&lt;/a&gt; to install the important gems for rails and created a quick rails 3 app.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;C:\Users\skim&amp;gt;gem install tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n rake --no-ri --no-rdoc
Successfully installed tzinfo-0.3.16
Successfully installed builder-2.1.2
Successfully installed memcache-client-1.7.8
Successfully installed rack-1.1.0
Successfully installed rack-test-0.5.3
Successfully installed rack-mount-0.4.5
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.5
Successfully installed activesupport-2.3.5
Successfully installed mime-types-1.16
Successfully installed mail-2.1.2
Successfully installed text-hyphen-1.0.0
Successfully installed text-format-1.0.0
Successfully installed thor-0.13.0
Due to a rubygems bug, you must uninstall all older versions of bundler for 0.9 to work
Successfully installed bundler-0.9.3
Successfully installed i18n-0.3.3
Successfully installed rake-0.8.7
17 gems installed  

C:\Users\skim&amp;gt;gem install rails --pre --no-ri --no-rdoc
Successfully installed activesupport-3.0.0.beta
Successfully installed activemodel-3.0.0.beta
Successfully installed actionpack-3.0.0.beta
Successfully installed arel-0.2.pre
Successfully installed activerecord-3.0.0.beta
Successfully installed activeresource-3.0.0.beta
Successfully installed actionmailer-3.0.0.beta
Successfully installed railties-3.0.0.beta
Successfully installed rails-3.0.0.beta
9 gems installed
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img src='/images/rails3beta.jpg' alt='Rails 3 Beta' /&gt;&lt;/p&gt;

&lt;p&gt;I recommend visiting &lt;a href='http://groups.google.com/group/rubyinstaller'&gt;RubyInstaller Google Group&lt;/a&gt; if you have any problems with the RubyInstaller.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/iLJ7CWJzC1Q" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/07/rails-3-beta-on-windows-using-rubyinstaller-187-rc2</feedburner:origLink></entry>
 
 <entry>
   <title>jekyll and github</title>
   
   <category term="--" />
   
   <category term="jekyll" />
   
   <category term="--" />
   
   <category term="github" />
   
   <category term="--" />
   
   <category term="codaset" />
   
   <link href="http://feedproxy.google.com/~r/sl4m/~3/Rr0JaDvSZPo/jekyll-and-github" />
   <updated>2010-02-04T23:30:00-08:00</updated>
   <id>http://skim.la/2010/02/04/jekyll-and-github</id>
   <content type="html">&lt;p&gt;I finally got &lt;a href='http://github.com/mojombo/jekyll'&gt;jekyll&lt;/a&gt; and github working together thanks to &lt;a href='http://chrismdp.github.com/'&gt;Chris Parson&amp;#8217;s&lt;/a&gt; github pages. I might throw this on &lt;a href='http://codaset.com/skim/skim_pages'&gt;codaset&lt;/a&gt; after I&amp;#8217;m more familiar with jekyll, but in the meantime, this will do. Now I need to figure out how to link this to my domain&amp;#8230;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/sl4m/~4/Rr0JaDvSZPo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://skim.la/2010/02/04/jekyll-and-github</feedburner:origLink></entry>
 
 
</feed>

