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

<channel>
	<title>Thinking Digitally &#187; Ruby</title>
	<atom:link href="http://thinkingdigitally.com/category/programming/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://thinkingdigitally.com</link>
	<description>programming for the fun of it</description>
	<lastBuildDate>Tue, 09 Feb 2010 04:55:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Capturing Output from PUTS in Ruby</title>
		<link>http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/</link>
		<comments>http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 08:36:13 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[mocha]]></category>
		<category><![CDATA[puts]]></category>
		<category><![CDATA[redirect output]]></category>
		<category><![CDATA[simplesem]]></category>
		<category><![CDATA[zentest]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/</guid>
		<description><![CDATA[When writing unit tests for my simplesem interpreter, one test in particular was problematic. In simplesem, the set write instruction prints output to the screen. // place Hello World! on the 'write' buffer set write, &#34;Hello World!&#34; Internally, the interpreter is just passing the second parameter, &#8220;Hello World!&#8221;, to the puts method in Ruby. This [...]]]></description>
			<content:encoded><![CDATA[<p>When writing unit tests for my <a href="http://thinkingdigitally.com/archive/a-simplesem-interpreter/">simplesem interpreter</a>, one test in particular was problematic. In simplesem, the <code>set write</code> instruction prints output to the screen.</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">// place Hello World! on the 'write' buffer
set write, &quot;Hello World!&quot;</pre></div></div>


<p>Internally, the interpreter is just passing the second parameter, &#8220;Hello World!&#8221;, to the <code>puts</code> method in Ruby. This makes it difficult to use traditional test/unit assertions to check that the simplesem instruction is working.</p>

<p>I eventually found two solutions for this. The first, suggested by <a href="http://flouri.sh/">David Stevenson</a> at Pivotal Labs, is to use <a href="http://github.com/floehopper/mocha/">mocha</a> to check that <code>puts</code> was called on the object.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'test/unit'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mocha'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> SimpleSemParserTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_set_stmt_write
    parser = SimpleSemParser.<span style="color:#9900CC;">new</span>
    parser.<span style="color:#9900CC;">expects</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:puts</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Hello World!&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    parser.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'set write, &quot;Hello World!&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">execute</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This solution is fine for most situations; Mocha will throw an exception if <code>puts</code> is not called. However in my case, it was unsuitable because <code>puts</code> was not being called on the SimpleSemParser object but instead on a <a href="http://treetop.rubyforge.org/">Treetop</a> syntax node that I did not easily have access to within the unit test.</p>

<p>I knew that if I could capture the output from the <code>puts</code> method into a variable I would be able write the test using a standard <code>assert_equal</code>. After some googling I discovered that this functionality is built into the <a href="http://www.zenspider.com/ZSS/Products/ZenTest/index.html">ZenTest</a> gem. After rewriting the test looked like this.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'test/zentest_assertions'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> SimpleSemParserTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_set_stmt_write
    out, err = util_capture <span style="color:#9966CC; font-weight:bold;">do</span> 
      parser = SimpleSemParser.<span style="color:#9900CC;">new</span>
      parser.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'set write, &quot;Hello World!&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">execute</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    assert_equal <span style="color:#996600;">&quot;Hello World!<span style="color:#000099;">\n</span>&quot;</span>, out.<span style="color:#CC0066; font-weight:bold;">string</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>This works great. However, should we decided that we do not want to use an external gem, with a little effort we can bypass ZenTest and implement <code>util_capture</code> ourselves.</p>

<p><span id="more-165"></span></p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'stringio'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> <span style="color:#CC00FF; font-weight:bold;">Kernel</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> capture_stdout
    out = <span style="color:#CC00FF; font-weight:bold;">StringIO</span>.<span style="color:#9900CC;">new</span>
    <span style="color:#ff6633; font-weight:bold;">$stdout</span> = out
    <span style="color:#9966CC; font-weight:bold;">yield</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> out
  <span style="color:#9966CC; font-weight:bold;">ensure</span>
    <span style="color:#ff6633; font-weight:bold;">$stdout</span> = STDOUT
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>Done! We extended the Kernel module with a method called <code>capture_stdout</code><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>. <code>capture_stdout</code> works by redirecting <code>$stdout</code> to an instance of <a href="http://www.ruby-doc.org/core/classes/StringIO.html">StringIO</a>. StringIO has all of the <a href="http://www.ruby-doc.org/core/classes/IO.html">IO</a> methods, but acts on a string instead of a file. After changing <code>$stdout</code> we yield to let the caller generate output. Once the yield is finished, we return the StringIO instance and add an ensure to guarantee that <code>$stdout</code> is reset to its default value. Adding <code>capture_stdout</code> to the Kernel module has the effect of giving <code>capture_stdout</code> a global scope so that it can be used anywhere.</p>

<p>With the exception that we that we renamed the method to <code>capture_stdout</code>, and are not returning <code>$stderr</code>, the unit test has not changed from the ZenTest version.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SimpleSemParserTest <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_set_stmt_write
    out = capture_stdout <span style="color:#9966CC; font-weight:bold;">do</span> 
      parser = SimpleSemParser.<span style="color:#9900CC;">new</span>
      parser.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'set write, &quot;Hello World!&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">execute</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    assert_equal <span style="color:#996600;">&quot;Hello World!<span style="color:#000099;">\n</span>&quot;</span>, out.<span style="color:#CC0066; font-weight:bold;">string</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>We end with a clean, very readable way to test Ruby methods that generate output without using any libraries.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>I prefer this name over &#8220;util_capture&#8221;.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A SIMPLESEM Interpreter</title>
		<link>http://thinkingdigitally.com/archive/a-simplesem-interpreter/</link>
		<comments>http://thinkingdigitally.com/archive/a-simplesem-interpreter/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 09:35:24 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[cs141]]></category>
		<category><![CDATA[simplesem]]></category>
		<category><![CDATA[treetop]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/a-simplesem-interpreter/</guid>
		<description><![CDATA[In my Programming Languages course, taught by Shannon Tauro we have been using a fake assembly language of sorts called SIMPLESEM to gain experience translating the semantics of a high level programming language, to a simple processor. Since SIMPLESEM is a made up language that was created just for our textbook, there was no way [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="https://eee.uci.edu/09w/16250/">Programming Languages course</a>, taught by <a href="http://www.ics.uci.edu/~stauro/">Shannon Tauro</a> we have been using a fake assembly language of sorts called SIMPLESEM to gain experience translating the semantics of a high level programming language, to a simple processor.</p>

<p>Since SIMPLESEM is a made up language that was created just for our textbook, there was no way for me to execute the SIMPLESEM programs that I was writing for the homework assignments. This was annoying because SIMPLESEM is a low level language which makes it hard to notice mistakes. Of course, it is very easy to make a mistake any time you are programming but it is even harder to catch those mistakes if you are working at close to assembly level.</p>

<p>As a fun exercise I implemented an <a href="http://github.com/robolson/simplesem">interpreter for SIMPLESEM</a> using Ruby and published it as a RubyGem. Fortunately, I choose to use Nathan Sobo&#8217;s <a href="http://treetop.rubyforge.org/">Treetop</a> gem to aide in the development. Using Treetop, I wrote a parsing expression grammar to parse SIMPLESEM commands. This resulted in my SIMPLESEM interpreter being a lot more flexible than I had originally anticipated. After I familiarized myself with the basics of writing Treetop grammars I found it very easy to make changes to my grammar definitions to add language features one by one.</p>

<p><span id="more-158"></span>
Installing the SIMPLESEM interpreter should be easy if you are on Linux or OS X, and possible if you are on Windows. The program is packaged as a rubygem. *nix folks should have rubygems packaged with their system. Windows users should visit the  <a href="http://www.rubygems.org/read/chapter/3">RubyGems</a> page to get running. Once you are setup with RubyGems, install the simplesem gem from Gemcutter:</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ sudo gem install simplesem --source http://gemcutter.org</pre></div></div>


<p>The gem installs a command called <code>simplesem</code>. To test it out download this <a href="http://github.com/robolson/simplesem/blob?path[]=sample_programs&amp;path[]=hello-world.txt&amp;raw=true">sample SIMPLESEM program</a> that prints &#8220;hello world!&#8221; five times. Run it by passing the name of the file as an argument to the command.</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ simplesem hello-world.txt
hello world!
hello world!
hello world!
hello world!
hello world!</pre></div></div>


<p>You can view other sample SIMPLESEM programs <a href="http://github.com/robolson/simplesem/tree/master/sample_programs">here</a>. To learn more about SIMPLESEM or the interpreter check out the <a href="http://github.com/robolson/simplesem/blob/master/README.textile">README</a>.</p>

<div class="resource-list"><dl>

<dt><a href="http://github.com/robolson/simplesem">
<img src="/images/icons/application_x-ruby.png" alt="SIMPLESEM Interpreter on GitHub" />
SIMPLESEM Interpreter</a></dt>
<dd>Source code available on GitHub.</dd>

</dl></div>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/a-simplesem-interpreter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails-doc.org is my new Rails Reference</title>
		<link>http://thinkingdigitally.com/archive/rails-docorg-is-my-new-rails-reference/</link>
		<comments>http://thinkingdigitally.com/archive/rails-docorg-is-my-new-rails-reference/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 18:32:27 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rails-doc]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/rails-docorg-is-my-new-rails-reference/</guid>
		<description><![CDATA[When working with a framework as large as Ruby on Rails its necessary to have a reference close by for&#8230; well just about everything. Until recently I was a big fan of gotAPI.com because I really appreciated the Ruby and Rails reference tied together. However, the Javascript autocomplete on their search box is broken in [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thinkingdigitally.com/wp-content/uploads/2008/07/rails-doc-logo.png" class="display-inline-right" alt="Rails-doc.org" />
When working with a framework <a href="http://api.rubyonrails.org/">as large as Ruby on Rails</a> its necessary to have a reference close by for&#8230; well just about everything. Until recently I was a big fan of <a href="http://www.gotapi.com/rubyrails">gotAPI.com</a> because I really appreciated the Ruby and Rails reference tied together. However, the Javascript autocomplete on their search box is broken in <a href="http://www.spreadfirefox.com/en-US/worldrecord/firefox3">Firefox 3</a> so I decided to try the new Rails reference site, <a href="http://rails-doc.org">Rails-doc.org</a>.</p>

<p>Rails-doc.org is an fairly ambitious project to create a community driven Rails documentation site. Basically they let users sign up and contribute notes to the existing Rails documentation. This certainly has the potential to be very useful, especially for new Rails hackers because sometimes the people who have been around the framework for a while just take things for granted.</p>

<p>Take the documentation for <a href="http://www.ruby-doc.org/core-1.8.6/classes/Date.html#M000620">strftime in the Date class</a> for example. There is no documentation listed for that method. Despite the fact that you clearly need documentation of the strftime options in order to use that method. Instead you have to know to look under <a href="http://www.ruby-doc.org/core-1.8.6/classes/Time.html#M000297">strftime in the Time class</a> for the documentation. While this is an example specific to Ruby documentation, these are the kinds of obvious problems that a community documentation website can help solve.</p>

<p>Right now Rails-doc.org has only been live for a month the so amount of community documentation feels very low. In the mean time I&#8217;ll be using the site for the official documentation that is already in place. Plus its the best looking rendering of the Rails documentation site out there. The Nodeta guys did a good job with the design. They also have a nice looking <a href="http://blog.nodeta.fi/">blog</a>.</p>

<p>It will be interested to see how many of the notes contributed to Rails-doc get ported to the official Rails documentation. This certainly feels like the easiest and most straightforward way to contribute to Rails documentation and I can see it becoming a testing ground for future contributions to the official docs.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/rails-docorg-is-my-new-rails-reference/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby-Poker 0.3.0</title>
		<link>http://thinkingdigitally.com/archive/ruby-poker-030/</link>
		<comments>http://thinkingdigitally.com/archive/ruby-poker-030/#comments</comments>
		<pubDate>Wed, 28 May 2008 08:04:33 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[poker]]></category>
		<category><![CDATA[ruby-poker]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/ruby-poker-030/</guid>
		<description><![CDATA[Ruby Poker has been updated! This release is largely a result of bug reports filed by Jim W. He took ruby poker to areas I had not previously thought to explore and he ran into a couple nasty bugs. They have all been fixed in Ruby-Poker 0.3.0. In addition the following changes were made that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rubyforge.org/projects/rubypoker/">Ruby Poker</a> has been updated! This release is largely a result of bug reports filed by <a href="http://rubyforge.org/users/asucis2001">Jim W</a>. He took ruby poker to areas I had not previously thought to explore and he ran into a couple nasty bugs. They have all been fixed in Ruby-Poker 0.3.0. In addition the following changes were made that users should be aware of.</p>

<p><span id="more-50"></span></p>

<h3>Comparing cards has changed</h3>

<p>Before 0.3.0 two cards objects were regarded as equal if they had the same face value. Resulting in a 6 of Spades being equal to a 6 of Clubs. After some thinking I decided that I did not like that and changed it so cards must have the same face value and same suit to be considered equal. This should not affect anyone unless they are creating and comparing Card objects directly.</p>

<h3>PokerHand#arranged&#95;hand has been replaced by PokerHand#sort&#95;using&#95;rank</h3>

<p>To sort a PokerHand there are a couple options. <a href="http://rubypoker.rubyforge.org/classes/PokerHand.html#M000016">PokerHand#by&#95;face</a> will sort a PokerHand in order from least to highest. But what if you have a pair and want to sort the cards based on the hand&#8217;s poker rank. For that there is <a href="http://rubypoker.rubyforge.org/classes/PokerHand.html#M000034">PokerHand#sort&#95;using&#95;rank</a> which was previously available as PokerHand#arranged&#95;hand but it wasn&#8217;t documented.</p>

<h3>Handling of duplicate cards</h3>

<p>Before 0.3.0 Ruby-Poker would not complain if you added four 8&#8242;s of Clubs to a PokerHand. I&#8217;ve added a configuration option so that you can tell Ruby-Poker to throw a tantrum if you try and add the same card to a PokerHand twice.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'ruby-poker'</span>  
PokerHand.<span style="color:#9900CC;">allow_duplicates</span> = <span style="color:#0000FF; font-weight:bold;">false</span>  
PokerHand.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;8c&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;8c&quot;</span>   <span style="color:#008000; font-style:italic;"># this throws a RuntimeError</span></pre></div></div>


<p>allow_duplicates is set to true by default so you will not notice anything different unless you choose to opt-in to the exceptions.</p>

<p><strong>That&#8217;s everything</strong></p>

<p>As always you can install ruby-poker with the gem command.</p>


<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">gem install ruby-poker</pre></div></div>


<p>Or <code>gem update ruby-poker</code> if you already have it installed to upgrade from an old version.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/ruby-poker-030/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: The Ruby Programming Language</title>
		<link>http://thinkingdigitally.com/archive/book-review-the-ruby-programming-language/</link>
		<comments>http://thinkingdigitally.com/archive/book-review-the-ruby-programming-language/#comments</comments>
		<pubDate>Tue, 27 May 2008 01:14:51 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[book review]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/book-review-the-ruby-programming-language/</guid>
		<description><![CDATA[For a long time now Dave Thomas Programming Ruby (aka. The Pickaxe) has been the standard in the Ruby community as the book to learn Ruby from. Unfortunately the Pickaxe is not the best programming book ever written. In fact, its bulk and slowness almost killed my inspiration to learn Ruby. I respect Dave Thomas [...]]]></description>
			<content:encoded><![CDATA[<iframe src="http://rcm.amazon.com/e/cm?t=zotrails-20&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596516177&#038;fc1=000000&#038;IS2=1&#038;lt1=_top&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;float:left;margin:0 10px 3px 0" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>

<p>For a long time now Dave Thomas <a href="http://www.pragprog.com/titles/ruby/programming-ruby"><em>Programming Ruby</em> (aka. The Pickaxe)</a> has been the standard in the Ruby community as the book to learn Ruby from. Unfortunately the Pickaxe is not the best programming book ever written. In fact, its bulk and slowness almost killed my inspiration to learn Ruby. I respect Dave Thomas a lot for what he does for the Ruby community but the Pickaxe and I just did not click.</p>

<p>Since I didn&#8217;t find the Pickaxe to be excellent reading material, I had been eagerly anticipating <a href="http://www.davidflanagan.com/">David Flanagan&#8217;s</a> <a href="http://www.oreilly.com/catalog/9780596516178/"><em>The Ruby Programming Language</em></a> to come out and unseat The Pickaxe as the de facto book to recommend to newcomers to Ruby.</p>

<p>I am happy to say that <em>The Ruby Programming Language</em> did not disappoint. I picked up this book solely expecting to just review it since I already comfortable programming in Ruby. However, once I started reading the book I found myself frequently learning things about Ruby that I didn&#8217;t know before. Not like little things either like, &#8220;oh that&#8217;s interesting&#8221;. I&#8217;m talking significant things like &#8220;holy crap that&#8217;s sweet&#8221;.</p>

<p>This book covers both Ruby 1.8 and Ruby 1.9. Initially this concerned me because as impressive as it is, it must have been quite a headache for the authors and was not sure how they were going to pull it off. It turns out to be pretty much a non-issue. The authors make a note of what is 1.8 or 1.9 only and it does not disturb the flow of the book since it doesnâ€™t come up too frequently. I do hope though that after Ruby 1.9 stable is released they upgrade the book and tear out all the 1.8 specific material. Since I currently use 1.8 on a daily basis I don&#8217;t mind having 1.8 material in there but after everything has shifted to 1.9 it would be rather irksome.</p>

<p>The style of the book is fairly straightforward. It starts with an introduction to how Ruby programs work and then goes into an explanation of Ruby datatypes and objects. The later chapters cover advanced topics like reflection and metaprogramming. The authors opted not to go the tutorial route, which I think, was a good approach since the book is not designed to be an &#8220;intro to programming&#8221; text.</p>

<p>In the preface of the book, the authors state:</p>

<blockquote>
  <p>[The Ruby Programming Language] is loosely modeled after the classic <em>The C Programming Language</em> by Kernighan and Ritchie and aims to document the Ruby language comprehensively but without the formality of a language specification. It is written for experienced programmers who are new to Ruby, and for current Ruby programmers who want to take their understanding and mastery of the language to the next level.</p>
</blockquote>

<p>O&#8217;Reilly is hoping that <em>The Ruby Programming Language</em> becomes the equivalent of K&amp;R&#8217;s <em>The C Programming Language</em> for Ruby and I hope it succeeds. I think that every language needs their own K&amp;R book for people to turn to as the definitive authority. That&#8217;s something that I feel like the Java programming language never had and it creates something of a hurdle when browsing for a Java book.</p>

<p>The third edition of the Pickaxe is in beta and will be coming out soon. I really hope it makes a strong showing when it hits the press because after the bang-up job Flanagan and Matz did with <em>The Ruby Programming Language</em>, there is no reason to look at the Pickaxe till then.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/book-review-the-ruby-programming-language/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby-Poker 0.2.4</title>
		<link>http://thinkingdigitally.com/archive/ruby-poker-024/</link>
		<comments>http://thinkingdigitally.com/archive/ruby-poker-024/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 04:42:46 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[poker]]></category>
		<category><![CDATA[ruby-poker]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/ruby-poker-024/</guid>
		<description><![CDATA[I just pushed out another release of the ruby-poker gem. The only change in this release is some code changes to achieve compatibility with Ruby 1.9. Initially I had thought that I would not need to change anything for 1.9 because ruby-poker-0.2.2 installed and ran through some quick examples without any trouble. However, I was [...]]]></description>
			<content:encoded><![CDATA[<p>I just pushed out another release of the <a href="http://rubyforge.org/projects/rubypoker/">ruby-poker</a> gem. The only change in this release is some code changes to achieve compatibility with Ruby 1.9.</p>

<p>Initially I had thought that I would not need to change anything for 1.9 because ruby-poker-0.2.2 installed and ran through some quick examples without any trouble. However, I was saved by my test suite when it quickly exposed a problem where I was calling <code>each</code> on a <code>String</code> object. The <code>each</code> method was removed from String in 1.9 so I made a quick change to work around it and once again I&#8217;m seeing nothing but dots.</p>

<p><img src="http://thinkingdigitally.com/wp-content/uploads/2008/04/rp-unit-tests-pass.png" alt="Rp Unit Tests Pass" /></p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/ruby-poker-024/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eager Loading with Ultrasphinx</title>
		<link>http://thinkingdigitally.com/archive/eager-loading-with-ultrasphinx/</link>
		<comments>http://thinkingdigitally.com/archive/eager-loading-with-ultrasphinx/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 08:44:17 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ultrasphinx]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/eager-loading-with-ultrasphinx/</guid>
		<description><![CDATA[Ultrasphinx is a great Rails plugin that wraps around the Sphinx full-text search engine. I am using Ultrasphinx to handle search queries on a personal project I&#8217;m working on and I ran into a situation where I wanted to eager load associated models for my search results. The method for doing this is not well [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html">Ultrasphinx</a> is a great Rails plugin that wraps around the <a href="http://www.sphinxsearch.com/">Sphinx full-text search engine</a>. I am using Ultrasphinx to handle search queries on a personal project I&#8217;m working on and I ran into a situation where I wanted to eager load associated models for my search results. The method for doing this is not well documented so I&#8217;m going to step through how to add eager loading to your Ultrasphinx searches.</p>

<p>I am actually going to show two ways to do this. The first is the way that <a href="http://blog.evanweaver.com/">Evan Weaver</a>, the creator of Ultrasphinx, recommends and the second way is the create a simple plugin that extends the Ultrasphinx plugin. The second way is my favorite because it provides the cleanest integration in my opinion but I&#8217;m going to demonstrate both methods so you can choose for yourself.</p>

<p><span id="more-36"></span></p>

<h2>Method 1</h2>

<p>To begin we need to make a class method that performs the eager loading in the model. Something like this:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">## app/models/course.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> Course
  ...
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_with_includes</span><span style="color:#006600; font-weight:bold;">&#40;</span>id<span style="color:#006600; font-weight:bold;">&#41;</span>
    find<span style="color:#006600; font-weight:bold;">&#40;</span>id, <span style="color:#ff3333; font-weight:bold;">:include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:professors</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>Notice how I&#8217;m using the familiar ActiveRecord include option to perform the eager loading like we would normally. The next and last step is to add the method to <code>client_options[:finder_methods]</code> in your <code>environment.rb</code>.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">## config/environment.rb  </span>
<span style="color:#6666ff; font-weight:bold;">Ultrasphinx::Search</span>.<span style="color:#9900CC;">client_options</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:finder_methods</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">unshift</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:find_with_includes</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>


<p>That&#8217;s it. Now to the second method.</p>

<h2>Method 2</h2>

<p>As I mentioned before, in this method we are going to create a simple plugin that will add functionality to Ultrasphinx. The code for this plugin was written by <a href="http://rubyforge.org/users/malesca/">Henrik N</a>.</p>

<p>Create a new folder in <code>vendor/plugins/</code> called <code>ultrasphinx_customizations</code>. The name can be anything you like as long as it starts with &#8220;ultrasphinx&#8221;. This is so our customizations are loaded after the actual Ultrasphinx plugin. Inside the folder create <code>init.rb</code> and place this line in it.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">## vendor/plugins/ultrasphinx_customizations/init.rb</span>
<span style="color:#CC00FF; font-weight:bold;">Dir</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/lib/*.rb'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">require</span> file <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>


<p>Now for the part of the plugin that actually does the work. Create a <code>lib</code> folder in <code>ultrasphinx_customizations</code> and create a new file in it called <code>eager_loading.rb</code> with the following contents.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">## vendor/plugins/ultrasphinx_customizations/lib/eager_loading.rb</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Allows specifying eager loading options as e.g.</span>
<span style="color:#008000; font-style:italic;"># Ultrasphinx::Search.client_options[:include]['MyKlass'] =&gt; [:user]</span>
<span style="color:#008000; font-style:italic;"># or directly in is_indexed like</span>
<span style="color:#008000; font-style:italic;"># is_indexed ..., :eagerly_load =&gt; [:user]</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Ultrasphinx::Search</span>.<span style="color:#9900CC;">client_options</span>.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">HashWithIndifferentAccess</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff3333; font-weight:bold;">:finder_methods</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'find_all_by_id_with_eager_loading'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_all_by_id_with_eager_loading</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>ids<span style="color:#006600; font-weight:bold;">&#41;</span>
    includes = <span style="color:#6666ff; font-weight:bold;">Ultrasphinx::Search</span>.<span style="color:#9900CC;">client_options</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'include'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    args = ids <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> includes<span style="color:#006600; font-weight:bold;">&#93;</span>
    find_all_by_id<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">is_indexed_with_include_option</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#6666ff; font-weight:bold;">Ultrasphinx::Search</span>.<span style="color:#9900CC;">client_options</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'include'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span> = options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:eagerly_load</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    is_indexed_without_include_option<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>; alias_method_chain <span style="color:#ff3333; font-weight:bold;">:is_indexed</span>, <span style="color:#ff3333; font-weight:bold;">:include_option</span>; <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>Sweet we&#8217;re done with the plugin. Now for the fun part. Remember in the model where we have our Ultrasphinx <code>is_indexed :fields =&gt; [...]</code> declaration? Thanks to our new customization we can add an <code>:eagerly_loaded</code> key and it will behave like an ActiveRecord find(:include => &#8230;). Here is what mine looks like.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">## app/models/course.rb</span>
&nbsp;
is_indexed  <span style="color:#ff3333; font-weight:bold;">:fields</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'course_number'</span>, <span style="color:#996600;">'title'</span>, <span style="color:#996600;">'term'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
            <span style="color:#ff3333; font-weight:bold;">:eagerly_load</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:professors</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>


<p>That&#8217;s all you have to do! I really enjoy the second method because it provides a seamless integration with the <code>is_indexed</code> call which seems to help me sleep at night.</p>

<p>Huge thanks to Henrik N for writing the ultrasphinx_customization code and Evan Weaver for writing Ultrasphinx.</p>

<p><strong>Updated 04/17/2008</strong>: Fixed incorrect statement about plugin names.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/eager-loading-with-ultrasphinx/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ruby-Poker 0.2.1</title>
		<link>http://thinkingdigitally.com/archive/ruby-poker-021/</link>
		<comments>http://thinkingdigitally.com/archive/ruby-poker-021/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 05:15:57 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[poker]]></category>
		<category><![CDATA[ruby-poker]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/ruby-poker-021/</guid>
		<description><![CDATA[Ruby-Poker 0.2.1 is an incremental update over the 0.2.0 release. The biggest change is the addition of the &#60;&#60; and delete methods to the PokerHand object. Making it possible to add and remove cards from a hand without creating a new PokerHand object. require 'rubygems' require 'ruby-poker' &#160; hand.PokerHand.new&#40;&#34;3d 3s 7h 7d&#34;&#41; hand.to_s # =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rubyforge.org/projects/rubypoker/" title="ruby-poker on rubyforge">Ruby-Poker 0.2.1</a> is an incremental update over the 0.2.0 release. The biggest change is the addition of the <code>&lt;&lt;</code> and <code>delete</code> methods to the <code>PokerHand</code> object. Making it possible to add and remove cards from a hand without creating a new <code>PokerHand</code> object.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'ruby-poker'</span>
&nbsp;
hand.<span style="color:#9900CC;">PokerHand</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;3d 3s 7h 7d&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
hand.<span style="color:#9900CC;">to_s</span>                   <span style="color:#008000; font-style:italic;"># =&gt; &quot;3d 3s 7h 7d (Two pair)&quot;</span>
&nbsp;
hand <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;7c&quot;</span>
hand.<span style="color:#9900CC;">to_s</span>                   <span style="color:#008000; font-style:italic;"># =&gt; &quot;3d 3s 7h 7d 7c (Full house)&quot;</span>
&nbsp;
hand.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;3d&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
hand.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;3s&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
hand.<span style="color:#9900CC;">to_s</span>                   <span style="color:#008000; font-style:italic;"># =&gt; 7h 7d 7c (Three of a kind)&quot;</span></pre></div></div>


<p>I&#8217;m always in the process of adding documentation to ruby-poker. At this point the majority of the public facing methods of the <code>PokerHand</code> and <code>Card</code> classes have been documented with examples. The ruby-docs are available online at <a href="http://rubypoker.rubyforge.org/" title="ruby-poker documentation">http://rubypoker.rubyforge.org/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/ruby-poker-021/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Rails has a low learning curve? Hardly. You need to know Ruby</title>
		<link>http://thinkingdigitally.com/archive/rails-has-a-low-learning-curve-hardly-you-need-to-know-ruby/</link>
		<comments>http://thinkingdigitally.com/archive/rails-has-a-low-learning-curve-hardly-you-need-to-know-ruby/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 04:36:16 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/rails-has-a-low-learning-curve-hardly-you-need-to-know-ruby/</guid>
		<description><![CDATA[Ruby on Rails is often (incorrectly) billed as the framework that makes web development easy. Unfortunately a lot of people take this to mean &#8220;Anyone can make a web site with Rails&#8221; or &#8220;You can get started with Rails in 15 minutes&#8220;. Unfortunately neither is the case but regardless hundreds of thousands of people1 are [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://thinkingdigitally.com/wp-content/uploads/2008/02/ruby-required.png" alt="Ruby Required" /></p>

<p><a href="http://www.rubyonrails.org/">Ruby on Rails</a> is often (incorrectly) billed as the framework that makes web development easy. Unfortunately a lot of people take this to mean &#8220;<em>Anyone</em> can make a web site with Rails&#8221; or &#8220;<em>You</em> can get started with Rails in <a href="http://www.rubyonrails.org/screencasts">15 minutes</a>&#8220;. Unfortunately neither is the case but regardless hundreds of thousands of people<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> are flocking to Rails to start making a web app for everything under the sun.</p>

<p>These people learn in hurry that Rails is actually quite a large beast<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> and jump right into working with Rails without taking time to learn the programming language that Rails uses&#8230; Ruby. Almost like Ruby doesn&#8217;t exist. If I had to guess I would say people coding Rails apps without actually knowing Ruby has inevitably lead to the Rails community&#8217;s pseudo status as a <a href="http://www.google.com/search?&amp;q=rails%20is%20a%20ghetto">ghetto</a>.</p>

<p>I must confess, I was one of the Rails coders who didn&#8217;t know Ruby when I first started with Rails. Very few people who come to Rails known Ruby due to Ruby&#8217;s limited popularity before Rails came along. For about the past 7 months I have been trudging along, learning more about Ruby every day<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup> and the code I write for Rails projects now is much better. Ruby programming constructs like blocks, lamba, proc, etc are fairly advanced topics that I am probably only beginning to comprehend.</p>

<p>Most people might think it is obvious that you would need to know a framework&#8217;s programming language before you started using the framework. Certainly you would not attempt J2EE development without first knowing Java. For some reason this has not always been the case with Rails.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Instant Rails has been downloaded over 400,000 times.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p><a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321445619">The Rails Way</a> which contains everything a Rails developer needs to know about Rails is 912 pages.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:3">
<p>Largely thanks to <a href="http://projecteuler.net">Project Euler</a>.&#160;<a href="#fnref:3" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/rails-has-a-low-learning-curve-hardly-you-need-to-know-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What&#8217;s New in Ruby-Poker 0.2.0</title>
		<link>http://thinkingdigitally.com/archive/whats-new-in-ruby-poker-020/</link>
		<comments>http://thinkingdigitally.com/archive/whats-new-in-ruby-poker-020/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 21:48:19 +0000</pubDate>
		<dc:creator>Rob Olson</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[poker]]></category>
		<category><![CDATA[ruby-poker]]></category>

		<guid isPermaLink="false">http://thinkingdigitally.com/archive/whats-new-in-ruby-poker-020/</guid>
		<description><![CDATA[Yesterday ruby-poker 0.2.0 was released. Here is a synopsis of what has changed. Hands are no longer limited to 5 cards! In order to play any poker game other than 5-card draw (like Texas Holdem) you need to evaluate hands containing more or less than 5 cards. Now you can with ruby-poker. holdem_hand = PokerHand.new&#40;&#34;Qc [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday <a href="http://rubyforge.org/projects/rubypoker/">ruby-poker</a> 0.2.0 was released. Here is a synopsis of what has changed.</p>

<h4>Hands are no longer limited to 5 cards!</h4>

<p>In order to play any poker game other than 5-card draw (like Texas Holdem) you need to evaluate hands containing more or less than 5 cards. Now you can with ruby-poker.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">holdem_hand = PokerHand.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Qc Qd Qs 5d 5h 8c 2h&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>   <span style="color:#008000; font-style:italic;"># Any number of cards you want</span></pre></div></div>


<p><span id="more-27"></span></p>

<h4>Specifying face cards using numbers is no longer supported</h4>

<p>Previous to 0.2.0 face cards could be specified using their number value like so:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">PokerHand.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;10c 11c 12c 13c 14c&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># old way</span></pre></div></div>


<p>This no longer works and face cards must be created using their letters:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">PokerHand.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Tc Jc Qc Kc Ac&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># new way</span></pre></div></div>


<h4>to_s on PokerHand objects includes rank</h4>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">hand1 = PokerHand.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Tc Jc Qc Kc Ac&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> hand1                <span style="color:#008000; font-style:italic;">#=&gt; Tc Jc Qc Kc Ac (Royal Flush)</span></pre></div></div>


<h4>Straights with a low Ace work now</h4>

<p>Previously straights like A-2-3-4-5 were not counted as being a straight by the old hand evaluator. This has been remedied in 0.2.0.</p>

<h3>Update now!</h3>

<p>If you have a previous version of the ruby-poker gem installed update with <code>sudo gem update</code>. Installing ruby-poker can still be done with <code>sudo gem install ruby-poker</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thinkingdigitally.com/archive/whats-new-in-ruby-poker-020/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
