<?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>Joey Gibson&#039;s Blog &#187; ruby</title>
	<atom:link href="http://joeygibson.com/category/tech/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://joeygibson.com</link>
	<description>Java, Clojure, Scala, Groovy, Ruby, Python, Lisp, Objective-C, OSX, politics, religion, Koine Greek, Tae Kwon Do, Spanish and much more!</description>
	<lastBuildDate>Wed, 08 Feb 2012 03:50:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Ruby + MySQL + Windows = SUCCESS! (Finally)</title>
		<link>http://joeygibson.com/2005/06/17/ruby-mysql-windows-success-finally/</link>
		<comments>http://joeygibson.com/2005/06/17/ruby-mysql-windows-success-finally/#comments</comments>
		<pubDate>Fri, 17 Jun 2005 13:02:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://RubyMySQL</guid>
		<description><![CDATA[If you do a Google for &#8220;ruby mysql windows&#8221; you will find, among other things, lots of people trying to use Ruby to access MySQL on a Windows system. I&#8217;ve been trying for some time, and have finally gotten things &#8230; <a href="http://joeygibson.com/2005/06/17/ruby-mysql-windows-success-finally/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><!-- _tech_ruby_RubyMySQL --> If you do a Google for &#8220;ruby mysql windows&#8221; you will find, among other  things, lots of people trying to use <a href="http://www.ruby-lang.org">Ruby</a> to access <a href="http://www.mysql.com">MySQL</a> on a Windows system. I&#8217;ve been  trying for some time, and have <em>finally</em> gotten things going.</p>
<p>About a year ago I found <a href="http://seagecko.org/thoughts/in-the-past/2004/09/09/ruby-mysql-and-windows/">this  article</a> in which he fought the same fight. He was able to get a working .so  file, using the .Net C++ compiler, and offered his binary, but that  won&#8217;t work for everyone. Specifically, a file compiled with VC7 isn&#8217;t  usable by VC6 (at least not that I could see).</p>
<p>Anyway, I followed his  advice to a point, and then started experimenting. I opened up  <tt>irb</tt> and started poking MKMF to see what I could  accomplish. What I finally ended up with is a hacked  <tt>extconf.rb</tt> that can be edited easily to get the library built  on your own system. It will work with both VC6 and VC7, by changing  one line in the file. Assuming that you have MySQL 4.1 installed in  the default location, and you are using VC6, and Ruby 1.8.2 is  installed in the default location, you should be able to do this</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">    ruby extconf.rb
    nmake
    nmake install</pre></div></div>

<p>and have everything compile and install. Notice that I said  <em>should</em>. You should still take a look at the file, near the top, to  see if the settings are appropriate for your system.</p>
<p>Once installed, you can use this module directly, or install <a href="http://ruby-dbi.sourceforge.net/">DBI</a> for that &#8220;standard&#8221;  interface. DBI will use the library you just built and installed, so  all you have to do is download the DBI module, then do this</p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;">    <span style="color: #b1b100; font-weight: bold;">cd</span> ruby-dbi-all
    ruby setup.rb config --with=dbi,dbd_mysql
    ruby setup.rb setup
    ruby setup.rb install</pre></div></div>

<p>If you want to install other DBD drivers, add them after  <tt>dbd_mysql</tt>. That should be it.</p>
<p><a href="/extconf.rb">Here&#8217;s</a> the hacked extconf.rb file.</p>
<p>There are only two lines you might need to change, and they are at the  top of the file with comments around them.</p>
<p>I have tested this slightly using the binary I built with VC6 and it  seems to work fine. I have not tested the VC7-compiled binary, because  I don&#8217;t have a Ruby distro that was compiled with VC7. Let me know if  these directions don&#8217;t work for you. Not that I can do anything about  it, but I could put a note here for others.</p>
<p>Also, notice that I used 8.3 pathnames, which is really ugly. I would  have been happy to use the pathnames with spaces, but VC6 doesn&#8217;t like  spaces in pathnames. VC7 can grok them fine, but not 6. Both  understand the 8.3, so it was just easier to use that.</p>
<p>One more thing. I don&#8217;t believe that installing Visual Studio.Net  installs the necessary header and library files for building non-.Net  binaries. IOW, you might not have <tt>windows.h</tt> which will cause  things not to work. If you download and install the Platform SDK, then  you&#8217;ll be fine. My extconf.rb will add the default Platform SDK  directory to the necessary paths, so if you have that installed, and  try to do a VC7 build, you should be ok.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2005/06/17/ruby-mysql-windows-success-finally/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I Am Bushed&#8230;</title>
		<link>http://joeygibson.com/2004/10/03/i-am-bushed/</link>
		<comments>http://joeygibson.com/2004/10/03/i-am-bushed/#comments</comments>
		<pubDate>Sun, 03 Oct 2004 08:50:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://Tired</guid>
		<description><![CDATA[Today is Day Three of RubyConf2004 and I&#8217;m tired. This has been a good conference. Lots of stuff to think about and play with. Lots of code flying around and lots of laptops all in one room. I was up &#8230; <a href="http://joeygibson.com/2004/10/03/i-am-bushed/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Today is Day Three of <a  href="http://www.rubycentral.org/conference/">RubyConf2004</a> and I&#8217;m  tired. This has been a good conference. Lots of stuff to think about  and play with. Lots of code flying around and lots of laptops all in  one room. I was up until 02:00 this morning working on an ADO adapter  for <a href="http://activerecord.rubyonrails.org/show/HomePage">Active  Record</a> in order to talk to <a  href="http://www.microsoft.com/sql/default.asp">SQL Server</a>. I&#8217;ve  got about 40 failing tests right now (out of 143) so I&#8217;m closing  in on finishing&#8230; It&#8217;s been interesting. I only just began looking at  Active Record yesterday morning, so I think I&#8217;m doing pretty  well. Active Record is an OR framework in <a  href="http://www.ruby-lang.org">Ruby</a> that is <em>really</em>  simple to work with. Very cool. It&#8217;s part of the <a  href="http://www.rubyonrails.org/show/HomePage">Rails</a> suite, which  is an <acronym title="Model View Controller">MVC</acronym> framework for  building websites in Ruby. Very intriguing.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2004/10/03/i-am-bushed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AtlRUG: Second Meeting</title>
		<link>http://joeygibson.com/2004/04/22/atlrug-second-meeting/</link>
		<comments>http://joeygibson.com/2004/04/22/atlrug-second-meeting/#comments</comments>
		<pubDate>Thu, 22 Apr 2004 16:12:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://AtlRUG2</guid>
		<description><![CDATA[The second meeting of the Atlanta Ruby User Group will be next Tuesday, April 27 at 7:00PM. We will continue with my introduction to Ruby presentation and discuss what others have been working on since the last meeting. I also &#8230; <a href="http://joeygibson.com/2004/04/22/atlrug-second-meeting/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The second meeting of the <a href="http://www.AtlRUG.org">Atlanta Ruby  User Group</a> will be next <strong>Tuesday, April 27 at  7:00PM</strong>. We will continue with my introduction to <a  href="http://www.ruby-lang.org">Ruby</a> presentation and discuss what  others have been working on since the last meeting. I also have a few  fairly cool demos to show.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2004/04/22/atlrug-second-meeting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atlanta Ruby User Group</title>
		<link>http://joeygibson.com/2004/03/08/atlanta-ruby-user-group/</link>
		<comments>http://joeygibson.com/2004/03/08/atlanta-ruby-user-group/#comments</comments>
		<pubDate>Mon, 08 Mar 2004 22:06:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://AtlRUG</guid>
		<description><![CDATA[If you read my stuff very often then you know that I am a huge fan of the Ruby programming language. I write a ton of Ruby code and went to RubyConf 2003, so there was only one other direction &#8230; <a href="http://joeygibson.com/2004/03/08/atlanta-ruby-user-group/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you read my stuff very often then you know that I am a  <em>huge</em> fan of the <a href="http://www.ruby-lang.org">Ruby</a>  programming language. I write a ton of Ruby code and went to <a  href="http://www.rubyconf.org/">RubyConf 2003</a>, so there was only  one other direction to take my love of Ruby: start a user group. So, I  have started the <a href="http://www.AtlRUG.org">Atlanta Ruby User  Group</a>. Our first meeting will be Tuesday, March 30 2004, at my  office in Norcross. There is a <a href="http://bravepoint.com/contact_us/contact_atl.html">map</a> at the web site and a <a  href="http://groups.yahoo.com/group/atlrug-announce">mailing list</a>. Rather than try to  restate the meeting announcement, I&#8217;m just going to  repost the email I sent to the mailing list here. If you want more info,  drop me an <a href="mailto:joey@joeygibson.com">email</a> and/or visit  the <a href="http://www.AtlRUG.org">group site</a>. If you are within  range of Atlanta, please come on out for the meeting.  <br/><br/><br />
<blockquote>  <tt>  Our first meeting will be Tuesday March 30 at 7:00 PM. The meeting  location is at my office in Norcross, on Peachtree Industrial Blvd.  There is a <a  href="http://bravepoint.com/contact_us/contact_atl.html">map</a>  on the website. We have classrooms, so it will be a comfortable environment.  <br/><br/>  This meeting will be a "get to know each other" type meeting where  we can discuss what, if anything, we've done with Ruby so far. I  will then present the first part of an introduction to Ruby, and  then discuss the future direction of the group. The meeting should  be finished at 8:30 PM.  <br/><br/>  Things we need to discuss are meeting frequency, topics, presenters  and commitments from group members as far as attendance goes. I'm  not suggesting that everyone must commit to being at every meeting,  but with a small group, if several people miss each meeting,  there won't be much "group" to the group, if you know what I  mean. As for frequency, I'm currently thinking a meeting every  other month (6 per year) but I'm open to suggestions.  <br/><br/>  Anyway, <a href="http://www.samspublishing.com">Sams</a> Publishing has agreed to send me a few copies of  The Ruby Way and Teach Yourself Ruby in 21 Days, so I will  have those to hand out. (The Ruby Way is an excellent book  [thanks, Hal]; I haven't seen the 21 Days book.) I will  provide drinks and some snacks for the first meeting,  but if we decide to have food at subsequent meetings,  then we need to also decide how we are going to pay for it.  Lots to discuss, eh?  <br/><br/>  So, be sure to mark Tuesday, March 30 on your calendar as  we kick off the Atlanta Ruby User Group!  </tt>  </p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2004/03/08/atlanta-ruby-user-group/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH Util Ruby Script</title>
		<link>http://joeygibson.com/2004/01/07/ssh-util-ruby-script/</link>
		<comments>http://joeygibson.com/2004/01/07/ssh-util-ruby-script/#comments</comments>
		<pubDate>Wed, 07 Jan 2004 09:18:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://SshUtil</guid>
		<description><![CDATA[OpenSSH, that ships with Cygwin has a nice utility called ssh-agent. This program is a daemon that will hold on to your keys so that hosts you are authorized to log on to will not continually ask for your password. &#8230; <a href="http://joeygibson.com/2004/01/07/ssh-util-ruby-script/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.openssh.com/">OpenSSH</a>, that ships with <a href="http://www.cygwin.com/">Cygwin</a> has a nice utility called <a href="http://mah.everybody.org/docs/ssh">ssh-agent</a>. This program  is a daemon that will hold on to your keys so that hosts you are  authorized to log on to will not continually ask for your  password. This is especially useful when working with <a href="http://www.cvshome.org">CVS</a> repositories over SSH. When you  run ssh-agent, it spits out text that should be evaluated to set two  environment variables that you will need in order to run ssh-add, to  actually add your keys to it. That output looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">SSH_AUTH_SOCK</span>=<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>ssh-mjKjm512<span style="color: #000000; font-weight: bold;">/</span>agent.512; 
<span style="color: #7a0874; font-weight: bold;">export</span> SSH_AUTH_SOCK;  
<span style="color: #007800;">SSH_AGENT_PID</span>=<span style="color: #000000;">1600</span>; 
<span style="color: #7a0874; font-weight: bold;">export</span> SSH_AGENT_PID;  
<span style="color: #7a0874; font-weight: bold;">echo</span> Agent pid <span style="color: #000000;">1600</span>;</pre></div></div>

<p>On a Unix system, it&#8217;s easy to capture  the output of ssh-agent and evaluate it, but under the &#8216;command shell&#8217;  that ships with Windows systems, which is so pathetically crippled that  my old Commodore 64&#8242;s BASIC-based shell is looking pretty good, you can&#8217;t do that.</p>
<p>So what are those poor saps, myself included, who are using Windows systems to do? <a href="http://www.ruby-lang.org">Ruby</a> to the rescue. I wrote a simple  script that executes ssh-agent, capturing the output, massaging it a  little, and then creating a batch file that I can run to set the  necessary variables. Simply redirecting the output to a batch file  won&#8217;t work because there are some Unix-isms, such as exporting the  variables, that don&#8217;t work on Windows. So, here&#8217;s the script:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!ruby   </span>
lines = <span style="color:#006600; font-weight:bold;">%</span>x<span style="color:#006600; font-weight:bold;">&#123;</span>ssh<span style="color:#006600; font-weight:bold;">-</span>agent<span style="color:#006600; font-weight:bold;">&#125;</span>   
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;c:/tmp/sde.bat&quot;</span>, <span style="color:#996600;">&quot;w&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span>   
  lines.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span>   
    chunks = line.<span style="color:#CC0066; font-weight:bold;">chomp</span>.<span style="color:#CC0066; font-weight:bold;">split</span> <span style="color:#996600;">';'</span>   
    <span style="color:#9966CC; font-weight:bold;">if</span> chunks<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> =~ <span style="color:#006600; font-weight:bold;">/</span>^SSH<span style="color:#006600; font-weight:bold;">/</span>  
      file.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;SET #{chunks[0]}&quot;</span>  
    <span style="color:#9966CC; font-weight:bold;">end</span>  
  <span style="color:#9966CC; font-weight:bold;">end</span>  
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>You can see that the script sends the captured and massaged output to a  batch file called &#8220;sde.bat&#8221; located in C:/tmp. You can change both of  these to suit your preference. Once the script runs, I simply execute  the generated batch file and then run ssh-add. The nice thing about  the generated batch file is that it lingers until the next time I run  the Ruby script. Thus as I open new console Windows I can re-run it to  get the environment variables set properly in each one.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2004/01/07/ssh-util-ruby-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mixer Remixed</title>
		<link>http://joeygibson.com/2003/09/17/mixer-remixed/</link>
		<comments>http://joeygibson.com/2003/09/17/mixer-remixed/#comments</comments>
		<pubDate>Wed, 17 Sep 2003 10:30:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://MixerReMixed</guid>
		<description><![CDATA[After reading several threads about the text scrmabler and various implementations, I revised my Ruby version and it&#8217;s now 21 lines shorter and much more Ruby-like. It makes far less of an attempt to deal with punctuation, but I think &#8230; <a href="http://joeygibson.com/2003/09/17/mixer-remixed/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After reading several threads about the <a href="http://www.livejournal.com/users/jwz/256229.html">text scrmabler</a> and various implementations, I revised my <a href="http://www.ruby-lang.org">Ruby</a> version and it&#8217;s now 21 lines shorter and much more Ruby-like. It makes far less of an attempt to deal with punctuation, but I think that&#8217;s OK. This <em>is</em> just a lark, after all. <br/><br/>
<div class="boxed">
<pre> <font color="#804040"> 1</font>  <font color="#a020f0">class </font><font color="#2e8b57"><b>Mixer</b></font> <font color="#804040"> 2</font>      private <font color="#804040"> 3</font>  <font color="#a020f0">    def </font><font color="#008080">randomize</font>(str) <font color="#804040"> 4</font>          <font color="#804040"><b>return</b></font> str <font color="#804040"><b>if</b></font> str.length < <font color="#ff00ff">4</font> <font color="#804040"> 5</font> <font color="#804040"> 6</font>          str =~<font color="#6a5acd"> /</font><font color="#daa520">\B.*\B</font><font color="#6a5acd">/</font> <font color="#804040"> 7</font>          first = <font color="#008080">$`</font> <font color="#804040"> 8</font>          last = <font color="#008080">$'</font> <font color="#804040"> 9</font>          first + (<font color="#008080">$&#038;</font>.split(<font color="#6a5acd">//</font>).sort_by {rand}.join) + last <font color="#804040">10</font>      <font color="#a020f0">end</font> <font color="#804040">11</font> <font color="#804040">12</font>      public <font color="#804040">13</font>  <font color="#a020f0">    def </font><font color="#008080">mix_file</font>(filename) <font color="#804040">14</font>          lines = <font color="#008080">IO</font>.readlines(filename) <font color="#804040">15</font> <font color="#804040">16</font>          mix_lines(lines) <font color="#804040">17</font>      <font color="#a020f0">end</font> <font color="#804040">18</font> <font color="#804040">19</font>  <font color="#a020f0">    def </font><font color="#008080">mix_string</font>(str) <font color="#804040">20</font>          mix_lines(str.split).join(<font color="#6a5acd">"</font><font color="#daa520"> </font><font color="#6a5acd">"</font>) <font color="#804040">21</font>      <font color="#a020f0">end</font> <font color="#804040">22</font> <font color="#804040">23</font>  <font color="#a020f0">    def </font><font color="#008080">mix_lines</font>(lines) <font color="#804040">24</font>          lines.collect! <font color="#804040"><b>do</b></font> <font color="#008080">|line|</font> <font color="#804040">25</font>              words = <font color="#008080">Array</font>.new <font color="#804040">26</font> <font color="#804040">27</font>              line.split(<font color="#6a5acd">/</font><font color="#daa520">\W</font><font color="#6a5acd">/</font>).each <font color="#804040"><b>do</b></font> <font color="#008080">|word|</font> <font color="#804040">28</font>                  words << randomize(word) <font color="#804040">29</font>              <font color="#804040"><b>end</b></font> <font color="#804040">30</font> <font color="#804040">31</font>              words.join(<font color="#6a5acd">"</font><font color="#daa520"> </font><font color="#6a5acd">"</font>) <font color="#804040">32</font>          <font color="#804040"><b>end</b></font> <font color="#804040">33</font>      <font color="#a020f0">end</font> <font color="#804040">34</font>  <font color="#a020f0">end</font> </pre>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2003/09/17/mixer-remixed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>By Popular Demand, I Give You&#8230; Mixer!</title>
		<link>http://joeygibson.com/2003/09/15/by-popular-demand-i-give-you-mixer/</link>
		<comments>http://joeygibson.com/2003/09/15/by-popular-demand-i-give-you-mixer/#comments</comments>
		<pubDate>Mon, 15 Sep 2003 16:12:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://Mixer</guid>
		<description><![CDATA[&#8220;Popular demand,&#8221; yeah&#8230; right&#8230; That&#8217;s the ticket. Anyway, I saw this blog entry by Jamie this morning which caused me to write a Ruby program to mix up the letters of words, leaving the first and last letter as they &#8230; <a href="http://joeygibson.com/2003/09/15/by-popular-demand-i-give-you-mixer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>&#8220;Popular demand,&#8221; yeah&#8230; right&#8230; That&#8217;s the ticket. Anyway, I saw <a href="http://www.livejournal.com/users/jwz/256229.html">this blog entry</a> by <a href="http://www.jwz.com">Jamie</a> this morning which caused me to write a <a href="http://www.ruby-lang.org">Ruby</a> program to mix up the letters of words, leaving the first and last letter as they were. I started out with a simple script, then I added better punctuation support, then I converted it to a class, then I wrote unit tests to run it. Anyway, somebody wanted to see it, so here it is. Is it great code? Probably not. Do I care? Not really. <br/><br/>
<div class="boxed">
<pre> <font color="#804040"> 1</font>  <font color="#a020f0">class </font><font color="#2e8b57"><b>Mixer</b></font> <font color="#804040"> 2</font>      private <font color="#804040"> 3</font>  <font color="#a020f0">    def </font><font color="#008080">randomize</font>(str) <font color="#804040"> 4</font>  <font color="#804040"><b>        if</b></font> str.length < <font color="#000080">4</font> <font color="#804040"> 5</font>              <font color="#804040"><b>return</b></font> str <font color="#804040"> 6</font>          <font color="#804040"><b>end</b></font> <font color="#804040"> 7</font> <font color="#804040"> 8</font>          letters = str.split(<font color="#6a5acd">//</font>) <font color="#804040"> 9</font> <font color="#804040">10</font>          first = letters[<font color="#000080">0</font>] <font color="#804040">11</font>          mid = letters[<font color="#000080">1</font>..(letters.length - <font color="#000080">2</font>)] <font color="#804040">12</font>          last = letters[letters.length - <font color="#000080">1</font>] <font color="#804040">13</font> <font color="#804040">14</font>          new_letters = <font color="#6a5acd">""</font> <font color="#804040">15</font> <font color="#804040">16</font>  <font color="#804040"><b>        while</b></font> mid &#038;&#038; mid.length > <font color="#000080">0</font> <font color="#804040">17</font>              len = mid.length <font color="#804040">18</font>              r = rand(len) <font color="#804040">19</font>              new_letters << mid.delete_at(r) <font color="#804040">20</font>          <font color="#804040"><b>end</b></font> <font color="#804040">21</font> <font color="#804040">22</font>          first + new_letters + last <font color="#804040">23</font>      <font color="#a020f0">end</font> <font color="#804040">24</font> <font color="#804040">25</font>      public <font color="#804040">26</font>  <font color="#a020f0">    def </font><font color="#008080">mix_file</font>(filename) <font color="#804040">27</font>          lines = <font color="#6a5acd">IO</font>.readlines(filename) <font color="#804040">28</font> <font color="#804040">29</font>          mix_lines(lines) <font color="#804040">30</font>      <font color="#a020f0">end</font> <font color="#804040">31</font> <font color="#804040">32</font>  <font color="#a020f0">    def </font><font color="#008080">mix_string</font>(str) <font color="#804040">33</font>          new_str = <font color="#6a5acd">""</font> <font color="#804040">34</font> <font color="#804040">35</font>          mix_lines(str.split).each <font color="#804040"><b>do</b></font> <font color="#6a5acd">|line|</font> <font color="#804040">36</font>              new_str << line <font color="#804040">37</font>          <font color="#804040"><b>end</b></font> <font color="#804040">38</font> <font color="#804040">39</font>          new_str <font color="#804040">40</font>      <font color="#a020f0">end</font> <font color="#804040">41</font> <font color="#804040">42</font>  <font color="#a020f0">    def </font><font color="#008080">mix_lines</font>(lines) <font color="#804040">43</font>          lines.collect! <font color="#804040"><b>do</b></font> <font color="#6a5acd">|line|</font> <font color="#804040">44</font>              new_line = <font color="#6a5acd">""</font> <font color="#804040">45</font> <font color="#804040">46</font>              line.split(<font color="#6a5acd">/</font><font color="#6a5acd">\s</font><font color="#daa520">+|,|\.|\!|\(|\)|\"|\'</font><font color="#6a5acd">/</font>).each <font color="#804040"><b>do</b></font> <font color="#6a5acd">|word|</font> <font color="#804040">47</font>                  new_line << randomize(word) << <font color="#6a5acd">"</font><font color="#daa520"> </font><font color="#6a5acd">"</font> <font color="#804040">48</font>              <font color="#804040"><b>end</b></font> <font color="#804040">49</font> <font color="#804040">50</font>              new_line <font color="#804040">51</font>          <font color="#804040"><b>end</b></font> <font color="#804040">52</font> <font color="#804040">53</font>          lines <font color="#804040">54</font>      <font color="#a020f0">end</font> <font color="#804040">55</font>  <font color="#a020f0">end</font> </pre>
</p></div>
<p> <br/> And the unit tests, which don&#8217;t actually test anything. <br/><br/>
<div class="boxed">
<pre> <font color="#804040"> 1</font>  <font color="#a020f0">require</font> <font color="#6a5acd">'</font><font color="#daa520">test/unit</font><font color="#6a5acd">'</font> <font color="#804040"> 2</font>  <font color="#a020f0">require</font> <font color="#6a5acd">'</font><font color="#daa520">mix</font><font color="#6a5acd">'</font> <font color="#804040"> 3</font> <font color="#804040"> 4</font>  <font color="#a020f0">class </font><font color="#2e8b57"><b>MixTest </b></font>< <font color="#6a5acd">Test</font>::<font color="#6a5acd">Unit</font>::<font color="#6a5acd">TestCase</font> <font color="#804040"> 5</font>  <font color="#a020f0">    def </font><font color="#008080">setup</font>() <font color="#804040"> 6</font>          <font color="#6a5acd">@mixer</font> = <font color="#6a5acd">Mixer</font>.new <font color="#804040"> 7</font>      <font color="#a020f0">end</font> <font color="#804040"> 8</font> <font color="#804040"> 9</font>  <font color="#a020f0">    def </font><font color="#008080">test_word</font>() <font color="#804040">10</font>          x = <font color="#6a5acd">@mixer</font>.mix_string(<font color="#6a5acd">"</font><font color="#daa520">testing</font><font color="#6a5acd">"</font>) <font color="#804040">11</font>          puts x <font color="#804040">12</font>          assert_not_equal(<font color="#6a5acd">"</font><font color="#daa520">testing</font><font color="#6a5acd">"</font>, x, <font color="#6a5acd">"</font><font color="#daa520">String not randomized</font><font color="#6a5acd">"</font>) <font color="#804040">13</font>      <font color="#a020f0">end</font> <font color="#804040">14</font> <font color="#804040">15</font>  <font color="#a020f0">    def </font><font color="#008080">test_string</font>() <font color="#804040">16</font>          x = <font color="#6a5acd">@mixer</font>.mix_string(<font color="#6a5acd">"</font><font color="#daa520">this is a humongous test, dangit</font><font color="#6a5acd">"</font>) <font color="#804040">17</font>          puts x <font color="#804040">18</font>      <font color="#a020f0">end</font> <font color="#804040">19</font> <font color="#804040">20</font>  <font color="#a020f0">    def </font><font color="#008080">test_file</font>() <font color="#804040">21</font>          article = <font color="#6a5acd">@mixer</font>.mix_file(<font color="#6a5acd">"</font><font color="#daa520">testfile.txt</font><font color="#6a5acd">"</font>) <font color="#804040">22</font>          <font color="#800000">#puts article</font> <font color="#804040">23</font>      <font color="#a020f0">end</font> <font color="#804040">24</font>  <font color="#a020f0">end</font> </pre>
</p></div>
<p> <br/> I&#8217;m sure someone will find this useful&#8230; Again, &#8220;yeah, right.&#8221; Ah well, it was a mildly amusing diversion&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2003/09/15/by-popular-demand-i-give-you-mixer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplicity and Consistency</title>
		<link>http://joeygibson.com/2003/07/08/simplicity-and-consistency/</link>
		<comments>http://joeygibson.com/2003/07/08/simplicity-and-consistency/#comments</comments>
		<pubDate>Tue, 08 Jul 2003 08:46:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://Simplicity</guid>
		<description><![CDATA[Mike Clark this morning has a bit of a nudge for Rael to give Ruby a try. Mike makes the following statement that I completely agree with The beauty of Ruby is its simplicity and consistency. With Ruby, I find &#8230; <a href="http://joeygibson.com/2003/07/08/simplicity-and-consistency/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.clarkware.com/cgi/blosxom/2003/07/07#RaelsDestiny">Mike Clark</a>  this morning has a bit of a nudge for <a href="http://www.raelity.org/archives/computers/programming/python/text_processing_in_python.html">Rael</a> to give <a href="http://www.ruby-lang.org">Ruby</a> a try. Mike makes the <a href="http://www.clarkware.com/cgi/blosxom/2002/10/04#ruby">following statement</a>  that I completely agree with<br />
<blockquote> The beauty of Ruby is its simplicity and consistency. With Ruby, I find myself writing code to get the job done rather than to appease the compiler. </p></blockquote>
<p> So true! Since Ruby is a dynamic language, there are no variable types to declare, no static checking; variables are just slots. The number of lines of Ruby code to do something is <em>far less</em> than the equivalent Java code, and I would argue more readable. You don&#8217;t have to jump through hoops to make the compiler happy, you just write your code to do what you need done. That&#8217;s it. It&#8217;s a beautiful thing. <br/><br/> The fact that regular expressions are baked right into the language is also a giant plus. This is how <a href="http://www.perl.com">Perl</a> does it, and Matz basically lifted this approach when he created Ruby. <a href="http://www.python.org">Python</a>&#8216;s regex support is not nearly as nice since you have to create a regex and call methods on it instead of using a regex literal and using special variables to get the groups, etc. Where having baked-in regex support <em>really</em> shines is in not having to escape backslashed atoms in the regex. Regexen in Java are even more difficult to read than usual because every backslash is doubled to keep the Java string parser from barfing on unknown escapes.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2003/07/08/simplicity-and-consistency/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kata 6</title>
		<link>http://joeygibson.com/2003/06/27/kata-6/</link>
		<comments>http://joeygibson.com/2003/06/27/kata-6/#comments</comments>
		<pubDate>Fri, 27 Jun 2003 13:34:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://Kata6</guid>
		<description><![CDATA[I took a swipe at implementing Dave Thomas&#8217; Kata 6 which is an assignment dealing with anagrams. The goal is to parse a list of 45000-ish words, finding all the words that are anagrams of other words in the file. &#8230; <a href="http://joeygibson.com/2003/06/27/kata-6/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I took a swipe at implementing <a href="http://www.pragprog.com/pragdave/Practices/Kata/KataSix.rdoc,v">Dave Thomas&#8217; Kata 6</a> which is an assignment dealing with anagrams. The goal is to parse a list of 45000-ish words, finding all the words that are anagrams of other words in the file. Dave claims there are 2,530 sets of anagrams, but I only got 2,506. I&#8217;m not sure where the disconnect is, but here&#8217;s my solution. I welcome any comments and critiques. <br/><br/>
<div class="boxed">
<pre> words = <font color="#008080">IO</font>.readlines(<font color="#6a5acd">"</font><font color="#daa520">wordlist.txt</font><font color="#6a5acd">"</font>)  anagrams = <font color="#008080">Hash</font>.new([])  words.each <font color="#804040"><b>do</b></font> <font color="#008080">|word|</font>     base = <font color="#008080">Array</font>.new     word.chomp!.downcase!      word.each_byte <font color="#804040"><b>do</b></font> <font color="#008080">|byte|</font>         base << byte.chr     <font color="#804040"><b>end</b></font>      base.sort!      anagrams[base.to_s] |= [word] <font color="#804040"><b>end</b></font>  <font color="#0000ff"># Find the anagrams by eliminating those with only one word</font> anagrams.reject! {<font color="#008080">|k, v|</font> v.length == <font color="#ff00ff">1</font>}  values = anagrams.values.sort <font color="#804040"><b>do</b></font> <font color="#008080">|a, b|</font>     b.length <=> a.length <font color="#804040"><b>end</b></font>  <font color="#008080">File</font>.open(<font color="#6a5acd">"</font><font color="#daa520">anagrams.txt</font><font color="#6a5acd">"</font>, <font color="#6a5acd">"</font><font color="#daa520">w</font><font color="#6a5acd">"</font>) <font color="#804040"><b>do</b></font> <font color="#008080">|file|</font>     values.each <font color="#804040"><b>do</b></font> <font color="#008080">|line|</font>         file.puts(line.join(<font color="#6a5acd">"</font><font color="#daa520">, </font><font color="#6a5acd">"</font>))     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  largest = anagrams.keys.max <font color="#804040"><b>do</b></font> <font color="#008080">|a, b|</font>     a.length <=> b.length <font color="#804040"><b>end</b></font>  puts <font color="#6a5acd">"</font><font color="#daa520">Total: </font><font color="#6a5acd">#{anagrams.length}</font><font color="#6a5acd">"</font> <font color="#0000ff">#</font> puts <font color="#6a5acd">"</font><font color="#daa520">Largest set of anagrams: </font><font color="#6a5acd">#{values[0].inspect}</font><font color="#6a5acd">"</font> <font color="#0000ff"># </font> print <font color="#6a5acd">"</font><font color="#daa520">Longest anagram: </font><font color="#6a5acd">#{anagrams[largest].inspect}</font><font color="#daa520"> </font><font color="#6a5acd">"</font> <font color="#0000ff"># </font> puts <font color="#6a5acd">"</font><font color="#daa520">at </font><font color="#6a5acd">#{largest.length}</font><font color="#daa520"> characters each</font><font color="#6a5acd">"</font> </pre>
</p></div>
<p> <br/> <strong>Update:</strong> Of course, 10 seconds after uploading the code, I see something I could change. Instead of sorting the anagram hash descending by array length, I could have done the following: <br/><br/>
<div class="boxed">
<pre> longest = anagrams.to_a.max <font color="#804040"><b>do</b></font> <font color="#008080">|a, b|</font>     a[<font color="#ff00ff">1</font>].length <=> b[<font color="#ff00ff">1</font>].length <font color="#804040"><b>end</b></font> </pre>
</p></div>
<p> <br/> This will sort and pull the largest one off. The key is bucket 0 and the interesting array is in bucket 1.</p>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2003/06/27/kata-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First Cut At Kata 8</title>
		<link>http://joeygibson.com/2003/06/20/first-cut-at-kata-8/</link>
		<comments>http://joeygibson.com/2003/06/20/first-cut-at-kata-8/#comments</comments>
		<pubDate>Fri, 20 Jun 2003 13:46:00 +0000</pubDate>
		<dc:creator>Joey Gibson</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://Kata8</guid>
		<description><![CDATA[Dave Thomas of the Pragmatic Programmers has started publishing programming problems, calling them Kata. He&#8217;s just published Kata 8 this morning and I&#8217;ve had a go at a solution. The problem is to take a supplied list of words and &#8230; <a href="http://joeygibson.com/2003/06/20/first-cut-at-kata-8/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.pragprog.com/pragdave">Dave Thomas</a> of the <a href="http://www.pragmaticprogrammer.com/index.html">Pragmatic Programmers</a> has started publishing programming problems, calling them <a href="http://www.pragprog.com/pragdave/Practices/Kata/Index.rdoc,v">Kata</a>. He&#8217;s just published <a href="http://www.pragprog.com/pragdave/Practices/Kata/KataEight.rdoc,v">Kata 8</a> this morning and I&#8217;ve had a go at a solution. The problem is to take a supplied list of words and go through it finding all the six letter words that are constructed from shorter words in the file. The full problem is to write the program in three different ways: one optimized for human consumption, one optimized for speed, and one that is highly extensible. <br/><br/> Presented below is my first cut at this kata. I think it is fairly readable, at 79 lines, so this probably will count as my &#8220;fit for human consumption&#8221; version. It&#8217;s relatively fast, completing in 11 seconds. <br/><br/> Comments? Critiques? <br/><br/>
<div class="boxed">
<pre> <font color="#a020f0">#!/usr/local/bin/ruby</font>  start = <font color="#008080">Time</font>.now  <font color="#0000ff"># Arrays for each class of word</font> fourLetters = <font color="#008080">Array</font>.new threeLetters = <font color="#008080">Array</font>.new twoLetters = <font color="#008080">Array</font>.new sixLetters = <font color="#008080">Array</font>.new  <font color="#0000ff"># Loop over the word list, segregating the words</font> <font color="#0000ff">#  to their respective array</font> <font color="#008080">IO</font>.foreach(<font color="#6a5acd">"</font><font color="#daa520">wordlist.txt</font><font color="#6a5acd">"</font>) <font color="#804040"><b>do</b></font> <font color="#008080">|line|</font>     line.chomp!.downcase!      <font color="#804040"><b>case</b></font> line.length     <font color="#804040"><b>when</b></font> <font color="#ff00ff">2</font>         twoLetters << line     <font color="#804040"><b>when</b></font> <font color="#ff00ff">3</font>         threeLetters << line     <font color="#804040"><b>when</b></font> <font color="#ff00ff">4</font>         fourLetters << line     <font color="#804040"><b>when</b></font> <font color="#ff00ff">6</font>         sixLetters << line     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  candidates = <font color="#008080">Array</font>.new  <font color="#0000ff"># Build up all combinations of four letters + two letters</font> <font color="#0000ff">#  and store in them as candidates</font> fourLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|four|</font>     twoLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|two|</font>         wc = four + two          candidates << wc     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  <font color="#0000ff"># Build up all combinations of three letters + three</font> <font color="#0000ff">#  letters and store them as candidates</font> threeLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|three|</font>     threeLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|otherThree|</font>         wc = three + otherThree         candidates << wc     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  <font color="#0000ff"># Finally, all combinations of two letters + two letters</font> <font color="#0000ff">#  + two letters and store those as candidates</font> twoLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|firstTwo|</font>     twoLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|secondTwo|</font>         twoLetters.each <font color="#804040"><b>do</b></font> <font color="#008080">|thirdTwo|</font>             wc = firstTwo + secondTwo + thirdTwo             candidates << wc         <font color="#804040"><b>end</b></font>     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  <font color="#0000ff"># Now get rid of dups and sort in place</font> candidates.uniq!.sort! puts <font color="#6a5acd">"</font><font color="#daa520">Candidates = </font><font color="#6a5acd">#{candidates.length}</font><font color="#6a5acd">"</font> <font color="#0000ff">#</font>  <font color="#0000ff"># And the two arrays together leaving only those words</font> <font color="#0000ff">#  that appear in both lists</font> matches = sixLetters &#038; candidates  <font color="#0000ff"># Now write the matches to a file</font> <font color="#008080">File</font>.open(<font color="#6a5acd">"</font><font color="#daa520">matches.txt</font><font color="#6a5acd">"</font>, <font color="#6a5acd">"</font><font color="#daa520">w</font><font color="#6a5acd">"</font>) <font color="#804040"><b>do</b></font> <font color="#008080">|file|</font>     matches.each <font color="#804040"><b>do</b></font> <font color="#008080">|word|</font>         file.puts(word)     <font color="#804040"><b>end</b></font> <font color="#804040"><b>end</b></font>  finish = <font color="#008080">Time</font>.now  puts <font color="#6a5acd">"</font><font color="#daa520">Started at </font><font color="#6a5acd">#{start}</font><font color="#6a5acd">"</font> puts <font color="#6a5acd">"</font><font color="#daa520">Finished at </font><font color="#6a5acd">#{finish}</font><font color="#6a5acd">"</font> puts <font color="#6a5acd">"</font><font color="#daa520">Total time </font><font color="#6a5acd">#{finish.to_i - start.to_i}</font><font color="#6a5acd">"</font> </pre>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://joeygibson.com/2003/06/20/first-cut-at-kata-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

