<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Calamity Lane - All</title>
  <id>tag:www.calamitylane.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.calamitylane.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.calamitylane.com/" rel="alternate" type="text/html"/>
  <updated>2008-02-25T03:53:52Z</updated>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2008-02-25:60</id>
    <published>2008-02-25T03:46:00Z</published>
    <updated>2008-02-25T03:53:52Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2008/2/25/finally-photos" rel="alternate" type="text/html"/>
    <title>Finally! Photos!</title>
<content type="html">
            My sincerest apologies to all our family and friends who have been waiting for pictures of the new baby!  Here are a few to whet your appetite:

&lt;a href=&quot;http://www.flickr.com/photos/calamitylane/sets/72157603981320805&quot; title=&quot;I'm trying to sleep&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2412/2290135326_7135c52c27.jpg&quot; height=&quot;375&quot; alt=&quot;I'm trying to sleep&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/calamitylane/sets/72157603981320805&quot; title=&quot;Fascinating&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3220/2290187824_783a8d48c9.jpg&quot; height=&quot;375&quot; alt=&quot;Fascinating&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/calamitylane/sets/72157603981320805&quot; title=&quot;Mr. Grumpypants&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2276/2289319015_8e070f5072.jpg&quot; height=&quot;375&quot; alt=&quot;Mr. Grumpypants&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/calamitylane/sets/72157603981320805&quot; title=&quot;Little Benjamin&quot;&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3111/2290239032_c3a7720f4c.jpg&quot; height=&quot;375&quot; alt=&quot;Little Benjamin&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;

You can look at the whole batch of 30 photos as a slideshow &lt;a href=&quot;http://www.flickr.com/photos/calamitylane/sets/72157603981320805&quot;&gt;here&lt;/a&gt;.
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2008-02-13:59</id>
    <published>2008-02-13T04:39:00Z</published>
    <updated>2008-02-13T04:40:18Z</updated>
    <link href="http://www.calamitylane.com/2008/2/13/the-votes-are-in" rel="alternate" type="text/html"/>
    <title>The Votes are In...</title>
<content type="html">
            &lt;p&gt;&#8230;and his name is&#8230;&lt;/p&gt;

&lt;p&gt;Benjamin Paul Alexander Budd!&lt;/p&gt;

&lt;p&gt;Thanks go out to everyone who participated in our survey.  Pics of the most awesome baby in the universe will be available shortly. :)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-12-03:58</id>
    <published>2007-12-03T03:10:00Z</published>
    <updated>2007-12-03T03:11:20Z</updated>
    <link href="http://www.calamitylane.com/2007/12/3/how-to-tell-when-your-wife-is-way-cooler-than-you" rel="alternate" type="text/html"/>
    <title>How to tell when your wife is way cooler than you...</title>
<content type="html">
            &lt;a href=&quot;http://www.nerdtests.com/ft_cg.php?im&quot;&gt;
&lt;img src=&quot;http://www.nerdtests.com/images/ft/cg.php?val=3616&quot; alt=&quot;My computer geek score is greater than 42% of all people in the world! How do you compare? Click here to find out!&quot;&gt; &lt;/a&gt;

Yes, that's Michelle's actual score.  Yes, it makes me sad.

(Confused? &lt;a href=&quot;http://en.wikipedia.org/wiki/Answer_to_Life,_the_Universe,_and_Everything&quot;&gt;This&lt;/a&gt; may help.)
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-11-30:57</id>
    <published>2007-11-30T06:06:00Z</published>
    <updated>2007-11-30T06:06:09Z</updated>
    <link href="http://www.calamitylane.com/2007/11/30/how-to-tell-you-ve-been-spending-too-much-time-in-front-of-the-computer" rel="alternate" type="text/html"/>
    <title>How to tell you've been spending too much time in front of the computer...</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.nerdtests.com/ft_cg.php?im&quot;&gt;
&lt;img src=&quot;http://www.nerdtests.com/images/ft/cg.php?val=0848&quot; alt=&quot;My computer geek score is greater than 100% of all people in the world! How do you compare? Click here to find out!&quot;&gt; &lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-10-01:54</id>
    <published>2007-10-01T03:03:00Z</published>
    <updated>2007-10-01T03:03:44Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2007/10/1/would-you-like-to-name-that-budd" rel="alternate" type="text/html"/>
    <title>Would you like to name that Budd?</title>
<content type="html">
            Take the survey:

&amp;lt;iframe allowtransparency=&quot;true&quot; title=&quot;HTML Form&quot; src=&quot;http://namethebudd.wufoo.com/embed/nameabudd/&quot; frameborder=&quot;0&quot; height=&quot;575&quot; style=&quot;width:100%;border:none&quot; scrolling=&quot;no&quot;&gt;&lt;a href=&quot;http://namethebudd.wufoo.com/forms/nameabudd/&quot; title=&quot;HTML form&quot;&gt;Fill out my Wufoo form!&lt;/a&gt;&amp;lt;/iframe&gt;
&lt;small&gt;&lt;a href=&quot;http://wufoo.com/&quot;&gt;Powered by Wufoo&lt;/a&gt;&lt;/small&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-09-23:13</id>
    <published>2007-09-23T05:54:00Z</published>
    <updated>2007-09-23T07:10:07Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2007/9/23/how-good-is-your-cooking" rel="alternate" type="text/html"/>
    <title>How good is your cooking?</title>
<content type="html">
            Are you this good?&lt;br&gt;
&lt;a href=&quot;http://www.flickr.com/photos/calamitylane/1100386556/&quot; title=&quot;Photo Sharing&quot;&gt;&lt;img src=&quot;http://www.calamitylane.com/assets/2007/9/23/1100386556_b7bb9322dd.jpg&quot; height=&quot;375&quot; alt=&quot;Delicious!&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;br&gt;&lt;br&gt;

That's right.  I made a PBJ sandwich so bad that &lt;em&gt;the jar of peanut butter immolated.&lt;/em&gt;
&lt;br&gt;&lt;br&gt;
It was actually kind of tasty, afterwards.  It's no coincidence that Michelle does most of the cooking.
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-05-02:12</id>
    <published>2007-05-02T03:06:00Z</published>
    <updated>2007-05-02T03:43:34Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2007/5/2/pictures-of-the-new-house" rel="alternate" type="text/html"/>
    <title>Pictures of the New House</title>
<content type="html">
            &lt;p&gt;Our first home. :)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/2&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1178072487_thumb.JPG&quot; alt=&quot;Architecture and Cute&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/2&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1177197181_thumb.JPG&quot; alt=&quot;Big Ol&#8217; House&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/2&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1178072324_thumb.JPG&quot; alt=&quot;AAAAAAGH!&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/2&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1177197055_thumb.JPG&quot; alt=&quot;A belchy favorite&quot; /&gt; &lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-27:9</id>
    <published>2007-04-27T04:26:00Z</published>
    <updated>2008-08-28T03:43:00Z</updated>
    <category term="Programming"/>
    <link href="http://www.calamitylane.com/2007/4/27/ruby-as-a-windows-service" rel="alternate" type="text/html"/>
    <title>Them what deals with th' Devil...</title>
<content type="html">
            &lt;p&gt;With my recent spate of GServer problems, I thought I&#8217;d post something that, surprisingly, turned out not to be much of a problem at all: turning a Ruby GServer into a Windows service.&lt;/p&gt;

&lt;p&gt;First, it helps tremendously if you already have Cygwin installed.  If you don&#8217;t, you should, as you get lots of UNIX-y command-line goodness (for example, a &#8220;Find In Files&#8221; functionality (grep) that actually finds stuff in files.  Uncanny!)&lt;/p&gt;

&lt;p&gt;I&#8217;d used Cygwin&#8217;s &#8220;cygrunsrv&#8221; to run Cygwin&#8217;s SSH server on Windows, because I love SSH and it seemed like a good idea at the time.  I didn&#8217;t realize you could use it to create service out of arbitrary programs.  With the following command (broken up for readability):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cygrunsrv /
           --install &quot;Bill Gates is Reading My Source Code Service&quot; /
           --path c:/ruby/bin/rubyw.exe /
           --args c:/Projects/source_viewer/source_viewer_server.rb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;you can be running your server under your very own Windows service!  (Pardon me while I run and gargle with some bleach.)&lt;/p&gt;

&lt;p&gt;Basically, you just need a name, the path to your Ruby executable, and the path to your application, and you&#8217;re good to go.  &lt;/p&gt;

&lt;p&gt;Notice here that I&#8217;ve used &#8220;rubyw.exe&#8221; which is a &#8220;windowless&#8221; version of Ruby.  It does not try to open Window&#8217;s crippled console, but runs strictly in the background, which is nice if you want to launch a server from a windows shortcut without distracting little black screens popping up.  I have no idea if this helps any, but I figured it couldn&#8217;t hurt (famous last words).&lt;/p&gt;

&lt;p&gt;One other important thing to be aware of is that Windows does not respond to standard system signals, so you will need to add the following method to your server class (&lt;a href=&quot;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/109133&quot;&gt;as seen here&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; def trap(signal)
   Kernel::trap(signal){yield} 
   Thread.new{loop{sleep 1}} # Stupid Windows...
 end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This lets you stop the service from services.msc&#8211; if you don&#8217;t have this, chances are good that the whole thing will hang when you try to stop or restart your service.&lt;/p&gt;

&lt;p&gt;There are a number of other (probably better) methods to turn programs into Windows services, but this one was quick, easy and served my needs well.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-16:8</id>
    <published>2007-04-16T00:52:00Z</published>
    <updated>2007-04-16T00:56:02Z</updated>
    <category term="Programming"/>
    <link href="http://www.calamitylane.com/2007/4/16/more-gserver-goodness" rel="alternate" type="text/html"/>
    <title>More GServer Goodness</title>
<content type="html">
            &lt;p&gt;In a previous posting, I &lt;a href=&quot;http://www.calamitylane.com/2007/4/10/rails-telnet-server&quot;&gt;mentioned&lt;/a&gt; that you could create a telnet server from a Rails application.  After having actually pushed a small GServer-based app into production, I can add a few notes to it:&lt;/p&gt;

&lt;h4&gt;ACCESSING YOUR SERVER REMOTELY&lt;/h4&gt;

&lt;p&gt;This one took way too long to figure out.  Every example I&#8217;ve seen online (&lt;a href=&quot;http://www.ruby-doc.org/stdlib/libdoc/gserver/rdoc/index.html&quot;&gt;even the library documentation&lt;/a&gt;) will only let you connect from localhost, which seemed even more exceptionally pointless than the stuff I usually do.  Most of the sample code runs along these lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'gserver'

class SomeNewServer &amp;lt; GServer
...
end

server = SomeNewServer.new 1234
server.start
server.join&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;where &#8220;1234&#8221; is the port used to access the server.  With this setup, you simply cannot access the server from another box, period.  Change the following line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server = SomeNewServer.new 1234&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server = SomeNewServer.new 1234, 'myserver.example.com'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;to make your new server accessible to the outside world.  You can use an IP address in place of the domain name.&lt;/p&gt;

&lt;p&gt;On the one hand, I was able to just guess at this parameter, and Ruby&#8217;s Principle of Least Surprise came through for me.  It&#8217;s more secure, as you don&#8217;t have to worry about accidentally exposing a massive security hole on your box during development.   On the other hand, it would have been nice to have it clearly listed out somewhere.  Here&#8217;s hoping that this saves some future googler a guessing game.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>sweetiepie</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-12:7</id>
    <published>2007-04-12T02:46:00Z</published>
    <updated>2007-07-18T05:01:12Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2007/4/12/introducing-harley-quin" rel="alternate" type="text/html"/>
    <title>Introducing Harley Quin</title>
<content type="html">
            &lt;p&gt;Well, we finally got a new pet!  &lt;/p&gt;

&lt;p&gt;It took us a while to get past the grief of Nanako&#8217;s passing, but we finally felt ready to get another kitty.  We searched petfinder.com and made a list of about 20 cats who were just unbelievably cute!  Then, we ran into problems.  We couldn&#8217;t possibly have 20 cats!  All we needed was one, maybe two!  So, we tried to cull.  But really, how can you cull out the cutest little pair of kitty eyes in the whole world?  Much less 20 pairs?!&lt;/p&gt;

&lt;p&gt;It just wasn&#8217;t working.  We had too many options!  So, to limit ourselves, we decided to head on down to the Petco on a Saturday afternoon to check out the kitties they had for adoption.  Surely that would make everything easier!  We&#8217;d only have 10 pair of cute little kitty eyes to decide from!  Not to mention kitty paws and tails and meows and purrs&#8230;oh, dear!&lt;/p&gt;

&lt;p&gt;Full of excitement, we drove out, walked through the store to the adoption area, looked inside&#8230;and saw dogs.  Not cuddly little kitties&#8230;.yipping puppies!  We were a bit disappointed, but I wanted to get some petting action in while we were there.  I love to cuddle animals!&lt;/p&gt;

&lt;p&gt;Perhaps we were in trouble from that moment.  The first couple of dogs were a bit hyper.  They were all jumping tongues and squirms of excitement.  They were cute, don&#8217;t get me wrong, but we wanted a kitty.  We were just in there to pet! &lt;/p&gt;

&lt;p&gt;The next dog in line was a big black lab mix who did NOT like men.  Eric couldn&#8217;t get close.  The poor puppy!  I mean, what could have been done to the poor baby to make him just hate and fear men like that?!&lt;/p&gt;

&lt;p&gt;Next one was a black and white dog who was laying there sleeping.  I bent down to pet him, and he only looked up at me with these tired friendly eyes and lay right back down.  He had the most amazing coat!  All soft and thick.  He was a cutie!  Apparently, he had been playing with the beagle puppy being kept next to him and had been plumb wore out!  They told us his name was Jester.&lt;/p&gt;

&lt;p&gt;We moved on to the remaing two dogs (the beagle next to Jester was in the process of being adopted) and left the adoption area.  But I just couldn&#8217;t get Jester&#8217;s awesome coat and laid-back attitude out of my head.  He had been awesome!  And the more I thought about him, the more I wanted to bring him home.&lt;/p&gt;

&lt;p&gt;I admit it&#8230;I bottom-lipped and sad-eyed Eric into getting him. LOL  Of course, we still had to get through the adoption process.&lt;/p&gt;

&lt;p&gt;We had attempted to adopt from the Humane Society once before and were turned down rather rudely.  They claimed there was too much &#8220;in and out&#8221; of animals for their liking.  They based their decision on the information we listed in one particular section of the application.  In this section, we were asked to list the animals we had owned in the previous 10 years, so to establish ourselves as experienced, qualified pet owners, I listed 4 animals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My cat Whiteface who died of old age at 13 years&lt;/li&gt;
&lt;li&gt;Mom&#8217;s cat Son who died at the age of 11 after being attacked by coons who got into the yard&lt;/li&gt;
&lt;li&gt;Kitty Kat, my mom&#8217;s dog who died at 8 or 9 quite suddenly (we never really knew what happened to him)&lt;/li&gt;
&lt;li&gt;Eric&#8217;s cat Ichabod who had to be given back to his original owner when he moved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I really don&#8217;t understand how that qualifies as too much &#8220;in and out&#8221; of animals.  We were very upset and the memory made us anxious about this adoption process through the Friends of Parkville Animal Shelter.&lt;/p&gt;

&lt;p&gt;If anyone would like to adopt an animal, PLEASE go through FOPAS!  They obviously love the animals they care for!  We were so very impressed with how efficient and nice everyone there was!  The adoption process, though not a breeze of course, was so refreshingly well-handled!  They were inquisitive without being prying.  They were concerned without being condescending.  I truly urge anyone in the Kansas City area to adopt from them!  We&#8217;re thinking of getting a kitty next (after summer classes with Harley), and we&#8217;ll definitely be getting our kitty from them!&lt;/p&gt;

&lt;p&gt;So, we now have a very cute dog who we renamed Harley Quin.&lt;/p&gt;

&lt;h3&gt;Next exciting episode:&lt;/h3&gt;

&lt;h2&gt;HOW CAN ONE DOG STINK SOOO BAD AND STILL BE SOOO CUTE?!&lt;/h2&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-10:3</id>
    <published>2007-04-10T03:33:00Z</published>
    <updated>2007-05-02T03:08:56Z</updated>
    <category term="Family"/>
    <link href="http://www.calamitylane.com/2007/4/10/harley-quin-the-amazing-wonder-dog" rel="alternate" type="text/html"/>
    <title>Harley Quin the Amazing Wonder Dog</title>
<content type="html">
            &lt;p&gt;Amazing in the sense of not exactly being the brightest bulb on the tree&#8230;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/1&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1175401538_thumb.jpg&quot; alt=&quot;Harley the dog&quot; /&gt; &lt;/a&gt;
&lt;a href=&quot;http://gallery.calamitylane.com/projects/show/1&quot;&gt;&lt;img src=&quot;http://gallery.calamitylane.com/system/assets/1175401582_thumb.JPG&quot; alt=&quot;Harley the dog&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&#8230;but making up for it with cute!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-10:5</id>
    <published>2007-04-10T03:32:00Z</published>
    <updated>2007-07-18T05:03:22Z</updated>
    <category term="Programming"/>
    <link href="http://www.calamitylane.com/2007/4/10/multi-line-strings-in-ruby" rel="alternate" type="text/html"/>
    <title>Multi-line strings in Ruby-- I Love Carriage Returns!</title>
<content type="html">
            &lt;p&gt;If you&#8217;ve ever done any serious development in VB or the old VBScript, you&#8217;ve probably done something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strSQL = &quot;SELECT o.* &quot; &amp; _
         &quot;FROM people p &quot; &amp; _
         &quot;INNER JOIN orders o &quot; &amp; _
         &quot;ON o.person_id = p.id &quot; &amp; _
         &quot;WHERE person_id = &quot; &amp; PersonID &amp; &quot;;&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;which is highly readable, but a huge pain to debug, especially when trying to cut-n-paste into the query window. How many of us have learned BkSp-BkSp-BkSp-Down-End-repeat-ad-infinitum? In fact, if you were to take every &#8216;&#8221; &amp;amp; _&#8217; and &#8217; &#8220;&#8217; I&#8217;ve ever deleted and stack them up on top of one another, you would probably end up with a stack&#8230; well, several inches high. Let&#8217;s face it, electrons just aren&#8217;t that big.&lt;/p&gt;

&lt;p&gt;Fed up with this state of affairs, many of us moved to C# for development, leading to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strSQL =        &quot;SELECT o.* &quot;;
strSQL = strSQL + &quot;FROM people p &quot;;
strSQL = strSQL + &quot;INNER JOIN orders o &quot;;
strSQL = strSQL + &quot;  ON o.person_id = p.id &quot;;
strSQL = strSQL + &quot;WHERE person_id = &quot; + PersonID.ToString() + &quot;;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the computer industry, this is called &#8220;progress.&#8221;&lt;/p&gt;

&lt;p&gt;Of course, if you wanted to make debugging simpler, you could stuff the entire string on one line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strSQL = &quot;SELECT o.* FROM people p INNER JOIN orders o ON o.person_id = p.id WHERE person_id = &quot; + PersonID.ToString() + &quot;;&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;which is a lot easier to cut-n-paste, but a lot less easy to read.&lt;/p&gt;

&lt;p&gt;Which is where Ruby comes in. Same query in Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strSQL = &quot;
    SELECT o.*
      FROM people p
      INNER JOIN orders o ON o.person_id = p.id
      WHERE person_id = #{person_id.to_s};
&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Isn&#8217;t it bee-yoo-tee-ful? Readable, functional, and oh so copy-pasteable. Also, it does not require extra punctuation to patch together a simple multi-line query.&lt;/p&gt;

&lt;p&gt;There are about 19,000 different ways to define a string in Ruby, but it&#8217;s the simple timesavers like this that make the language really shine.&lt;/p&gt;

&lt;p&gt;Of course, if you were using Rails, you could just&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Person.find(person_id).orders&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#8230;which just goes to show how much smarter and more sexually attractive Railers are than everybody else.&lt;/p&gt;

&lt;p&gt;NOTE: Originally, I was going to include connection and execution of the query, but that would have blown the VBScript and Ruby examples up an extra four lines of code each. Using recommended practices, it would have bloated the C# code up another 15 lines, plus a stored procedure definition.&lt;/p&gt;

&lt;p&gt;The Rails example would still have been only one line. Simplicity ftw!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.calamitylane.com/">
    <author>
      <name>calamitous</name>
    </author>
    <id>tag:www.calamitylane.com,2007-04-10:4</id>
    <published>2007-04-10T03:30:00Z</published>
    <updated>2007-04-16T00:56:49Z</updated>
    <category term="Programming"/>
    <link href="http://www.calamitylane.com/2007/4/10/rails-telnet-server" rel="alternate" type="text/html"/>
    <title>How to Turn a Rails Application Into a Telnet Server in 30 Lines of Code!</title>
<summary type="html">&lt;p&gt;Ruby on Rails is a beautiful thing; simple, fast, and powerful. As they say, it takes the pain out of web development.&lt;/p&gt;

&lt;p&gt;I&#8217;m fortunate enough to have been able to use Rails at work for a few months now, and the more I learn about the Rails framework and the Ruby language, the more enamored I become of the simplicity, beauty, and zen-like nature of these tools. But you didn&#8217;t come here to see me gush with adoration like a schoolgirl at an Elvis concert (I hope), you came to see:&lt;/p&gt;

&lt;h4&gt;How to Turn a Rails Application Into a Telnet Server in 30 Lines of Code!&lt;/h4&gt;</summary><content type="html">
            &lt;p&gt;Ruby on Rails is a beautiful thing; simple, fast, and powerful. As they say, it takes the pain out of web development.&lt;/p&gt;

&lt;p&gt;I&#8217;m fortunate enough to have been able to use Rails at work for a few months now, and the more I learn about the Rails framework and the Ruby language, the more enamored I become of the simplicity, beauty, and zen-like nature of these tools. But you didn&#8217;t come here to see me gush with adoration like a schoolgirl at an Elvis concert (I hope), you came to see:&lt;/p&gt;

&lt;h4&gt;How to Turn a Rails Application Into a Telnet Server in 30 Lines of Code!&lt;/h4&gt;
&lt;p&gt;Ruby on Rails is a beautiful thing; simple, fast, and powerful. As they say, it takes the pain out of web development.&lt;/p&gt;

&lt;p&gt;I&#8217;m fortunate enough to have been able to use Rails at work for a few months now, and the more I learn about the Rails framework and the Ruby language, the more enamored I become of the simplicity, beauty, and zen-like nature of these tools. But you didn&#8217;t come here to see me gush with adoration like a schoolgirl at an Elvis concert (I hope), you came to see:&lt;/p&gt;

&lt;h4&gt;How to Turn a Rails Application Into a Telnet Server in 30 Lines of Code!&lt;/h4&gt;

&lt;p&gt;First, some code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby
require 'config/environment'
require 'gserver'

class TestServer &amp;lt; GServer
  def serve( io )
    begin
      io.puts &quot;&gt;&gt; WELCOME &amp;lt;&amp;lt;&quot;
      loop do
        begin
          telnet_input = io.gets
          break if telnet_input =~ /\Aquit\b/
          io.puts eval(telnet_input)
        rescue Exception
          io.puts &quot;Oops - &quot; + $!
        end
        log &quot;Rec'd &quot; + telnet_input
      end
      io.puts &quot;&gt;&gt; GOODBYE &amp;lt;&amp;lt;&quot;
      io.close
    rescue Exception
      puts &quot;OOPS - &quot; + $!
      raise
    end
  end
end

ts = TestServer.new 1234
ts.start
ts.audit = true
ts.join&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;This code should work, as is, on just about any Rails application (as far as I&#8217;ve been able to tell; it&#8217;s worked on the few I&#8217;ve tried).&amp;lt;/p&gt;

&amp;lt;p&gt;Last night I was tooling around, playing with code. I&#8217;d had an idea for some server software I&#8217;d like to write, so I mocked up a quick throwaway system in Rails, and started playing around with some of the logic. I liked the results, and I&#8217;d already decided I wanted to write the server in Ruby, but the thought of taking all that functionality and porting everything to DBI calls or whatever was handy just made me tired, especially since Rails does all of the tedious database tasks for you.&amp;lt;/p&gt;

&amp;lt;p&gt;Fortunately, I&#8217;m slowly learning that Ruby is written for lazy programmers, and after a little googling and some educated guesses, I was able to whack the entire Rails app into a script simply by including:&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;require 'config/environment'&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;&#8230;at the top of a file in the project root. This makes everything available (so far as I&#8217;ve been able to tell) to your application.&amp;lt;/p&gt;

&amp;lt;p&gt;For a piece-by-piece analysis:&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;#!/usr/bin/env ruby
require 'config/environment'
    require 'gserver'

class TestServer &amp;lt; GServer
  def serve( io )&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;This sets the scripting environment, includes the Rails app, and makes the &#8220;GServer&#8221; class available. GServer is a freebie that comes with Ruby, so there&#8217;s no need for gem installs or other libraries. We&#8217;re then creating our own class which inherits from GServer, and overriding its &#8220;serve&#8221; method.&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;      io.puts &quot;&gt;&gt; WELCOME &amp;lt;&amp;lt;&quot;
      loop do
        telnet_input = io.gets
        break if telnet_input =~ /\Aquit\b/
        io.puts eval(telnet_input)
        log &quot;Rec'd &quot; + telnet_input
      end
      io.puts &quot;&gt;&gt; GOODBYE &amp;lt;&amp;lt;&quot;
      io.close&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;This is the heart of the server (note that I&#8217;ve left out the exception handling for readability). Simply speaking, the serve() method is what handles user connections, and the &#8220;io&#8221; object lets us do gets and puts across the wire.&amp;lt;/p&gt;

&amp;lt;p&gt;When a user connects, we spit out a welcome message, then go into an endless loop that responds to user requests. The following:&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;telnet_input = io.gets&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;&#8230;grabs whatever line the user types in. This line:&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;break if telnet_input =~ /\Aquit\b/&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;&#8230;kicks us out of the loop if the user types &#8220;quit&#8221;. Note that I&#8217;m using a regex instead of a static string because io.gets() returns the linefeed that the user types in, and this was an easy way to cheat out the functionality. The &#8220;\A&#8221; portion of the regex matches the beginning of the string, and the &#8220;\b&#8221; matches a &#8220;word boundary&#8221; character, in this case, the linefeed.&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;        io.puts eval(telnet_input)
        log &quot;Rec'd &quot; + telnet_input&amp;lt;/code&gt;&amp;lt;/pre&gt;

&amp;lt;p&gt;The first line here does an eval() on whatever the user typed in, returning the value back across the wire. This should allow the user to run any command that Ruby (and your Rails app) will accept. The second line spits whatever the user typed in to the console where the server is running.&amp;lt;/p&gt;

&amp;lt;pre&gt;&amp;lt;code&gt;      io.puts &quot;&gt;&gt; GOODBYE &amp;lt;&amp;lt;&quot;
      io.close&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the loop is broken, we burp out a fond farewell and cleanly close the connection.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ts = TestServer.new 1234
ts.start
ts.audit = true
ts.join&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The rest of the code just sets a few variables and kicks on the service. The &#8220;1234&#8221; on the creation of the &#8220;ts&#8221; object sets the listening port. Turning on auditing allows us to see when someone logs on and off from the console (which can be redirected to a log file).&lt;/p&gt;

&lt;h5&gt;CAVEATS:&lt;/h5&gt;

&lt;p&gt;This is an extremely simple server. It has no security, no performance optimization, and probably has more holes than a cheesecloth factory. It is very naive, and while it technically allows multiple users to log on, they&#8217;ll all share the same class variables. Really, it&#8217;s only interesting at this point to show that it can be done.&lt;/p&gt;

&lt;p&gt;That having been said, the ease with which it was accomplished is one of the many testaments to Ruby&#8217;s power and simplicity. I&#8217;ve been programming for many years, coded a number of servers, and this was the first time I&#8217;ve ever felt drunk with power after a coding session. &#8220;I can do anything!&#8221; I bellowed as I reeled around the room, knocking old monitors and dusty programming tomes off the desk. &#8220;No one can stop me!&#8221; Fortunately, my wife, who is a lot more level-headed than I am, pointed out that she could, indeed, stop me, since it had gone past two in the morning.&lt;/p&gt;
          </content>  </entry>
</feed>
