<?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"
	>

<channel>
	<title>nearly random</title>
	<atom:link href="http://www.johnbaylor.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johnbaylor.org</link>
	<description>but with a nefarious purpose</description>
	<pubDate>Thu, 02 Oct 2008 05:02:43 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<item>
		<title>Last of a Generation</title>
		<link>http://www.johnbaylor.org/2008/10/01/last-of-a-generation/</link>
		<comments>http://www.johnbaylor.org/2008/10/01/last-of-a-generation/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 05:02:43 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/?p=41</guid>
		<description><![CDATA[My aunt Barbara passed away yesterday. We were never close, but she was the last of her siblings to pass on, even though she was the oldest. I know that was hard on her. Now its finally her turn. May she find rest.
She played a pivotal role in my life, long before I was even [...]]]></description>
			<content:encoded><![CDATA[<p>My aunt Barbara passed away yesterday. We were never close, but she was the last of her siblings to pass on, even though she was the oldest. I know that was hard on her. Now its finally her turn. May she find rest.</p>
<p>She played a pivotal role in my life, long before I was even conceived. After her mother, my grandmother, had passed away, Barb took it upon herself to put my mother through college. I doubt she ever understood this nuclear engineering thing my mother studied, but she supported it. And eventually my mother met another engineer and here I am today.</p>
<p>It wasn&#8217;t unexpected - she had been declining for a while - but I&#8217;m surprised at how choked up I am about her passing. Outspoken, disapproving, warm and alive - often in the same sentence.</p>
<p>I remember a message she once left on our answering machine. Her voice sounded so similar to my dead mother&#8217;s voice, with the same Pennsylvania accent, that it sent chills up my spine.</p>
<p>Thanks Barb, for all you&#8217;ve done and all you were - you&#8217;ll be missed - and in the end, what more is there, than to be missed?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/10/01/last-of-a-generation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Self-Modifying Code? Or Self-Creating Code?</title>
		<link>http://www.johnbaylor.org/2008/04/20/self-modifying-code-or-self-creating-code/</link>
		<comments>http://www.johnbaylor.org/2008/04/20/self-modifying-code-or-self-creating-code/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 19:49:20 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/04/20/self-modifying-code-or-self-creating-code/</guid>
		<description><![CDATA[[aside: Why write an email that will be read by just one or two people when you can instead write a blog post that will be seen by... uh... one or two people?]
I was recently discussing the problem of tracing program execution through code that doesn&#8217;t exist.  Sometimes, usually to understand and debug a program, [...]]]></description>
			<content:encoded><![CDATA[<p>[aside: Why write an email that will be read by just one or two people when you can instead write a blog post that will be seen by... uh... one or two people?]</p>
<p>I was recently discussing the problem of tracing program execution through code that doesn&#8217;t exist.  Sometimes, usually to understand and debug a program, you need to trace through it. If the code doesn&#8217;t exist, its hard to follow where it goes. Actually, the code exists, its just not in source control or otherwise easily searchable.  Let me explain.</p>
<p>In Ruby, whose source code is a lot like its executable format, its trivial to write code that writes code - so you, the programmer, don&#8217;t have to. The Rails web framework uses this a lot, for creating whatever form of &#8216;find&#8217; strikes your fancy: find_by_firstname, find_by_firstname_and_gender, find_by_pet_species_and_viciousness, etc. - as long as your database table has the appropriately named columns then it will find what you&#8217;re looking for with no work on your part!  Actually, some work is required - you need to know that most any routine starting with &#8216;find&#8217; is probably auto-generated by Rails and thus will be un-findable in the source tree.</p>
<p>A more complex example is the routing helpers - a shorthand way of saying &#8220;put a link here on <em>this </em>web page that will take the user to <em>that</em> web page over there.  Until you realize that most any method ending in &#8216;path&#8217; is a URL helper then you&#8217;ll be confused by code that references user_edit_path or formatted_pet_list_path or formatted_pet_species_list_path.  The last one says that you want to get the path to a specially-formatted list of the various pet species represented by the system (e.g. &#8220;http://myPetSite.com/pet_species/list.csv&#8221;). Fairly clear once you know what it does, but fairly obtuse until you get to that point.  And it is, trust me on this, shorter, more maintainable and more clear than the alternative (after, of course, you learn to read it).</p>
<p>So this difficulty in finding the source to &#8220;formatted_pet_species_list_path&#8221; (or something like that) started a discussion that eventually got around to the idea that Ruby and Rails uses code to write code.</p>
<p>&#8220;Its the 11th commandment&#8221;, said one, &#8221; - thou shalt not write self-modifying code!&#8221;</p>
<p>Yes and no. Call me irrationally exuberant or say that I drank some sugary flavored colored water - but I don&#8217;t think its as cut-and-dried as it used to be.  This commandment, when Moses brought it down from on high, was written for a compiled language, where the source was very very different from the executing code, and it actually did <em>modify </em>the code being executed.  This is bad bad bad - its hard to understand, it leads to intractable bugs, it&#8217;ll make you go blind, melt glaciers and other bad stuff.  No argument there.</p>
<p>But is this what Rails is doing with Ruby? I&#8217;d say its different.  Instead of <em>modifying </em>existing code it is merely <em>creating </em>code that did not exist before. Its more akin to a pre-processor that could, just before compiling a program, generate all the permutations of finding database rows from columns X, Y and Z (and any number of others).  Looked at this way, it appears to be similar to a C++ template - generic code that a programmer has written to simplify the writing of code that does similar things in similar ways.  The main difference is that with Ruby there is no pre-processor - the routine gets created at the time it is first used.</p>
<p>The &#8220;template&#8221; in this case is a routine called method_missing that gets handed the name and arguments of any routine that doesn&#8217;t exist.  It looks for a function name matching the form &#8216;find_by_<em>X</em>&#8216; where <em>X</em> makes sense for the database table in question (of course, if it doesn&#8217;t match the correct format then it just passes the name and arguments onward for some other routine to either make sense of or to burp up an error).  Once the routine is created it is available to be called again, with none of the overhead incurred when it was first created. More importantly, it was created with no additional overhead on the part of the programmer - to write it, test it, debug it or modify it. This, in my opinion, is a huge advantage - but I&#8217;m a lazy developer who doesn&#8217;t want to write or debug any code that I don&#8217;t have to.</p>
<p>Kool-aid anyone?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/04/20/self-modifying-code-or-self-creating-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Its Official - My Old Product is Dead</title>
		<link>http://www.johnbaylor.org/2008/03/20/its-official-my-old-product-is-dead/</link>
		<comments>http://www.johnbaylor.org/2008/03/20/its-official-my-old-product-is-dead/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 23:22:38 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/03/20/its-official-my-old-product-is-dead/</guid>
		<description><![CDATA[Pay By Touch To Shut Down All Biometric Services Immediately 
Biometric authentication transactions to cease at 11:59:59PM March 19, 2008
SAN FRANCISCO - (March 19, 2008) - Solidus Networks, Inc., dba Pay By Touch, regretfully announced today that it will no longer process biometric transactions on behalf of its merchant customers and consumer membership base, as [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="text-align: center" align="center"><strong><span style="font-size: 10pt; font-family: 'Arial','sans-serif'"><center>Pay By Touch To Shut Down All Biometric Services Immediately </center></span></strong></p>
<p style="text-align: center" align="center"><em><span style="font-size: 10pt; font-family: 'Arial','sans-serif'">Biometric authentication transactions to cease at 11:59:59PM March 19, 2008</span></em></p>
<p><strong><span style="font-size: 10pt; font-family: 'Arial','sans-serif'">SAN FRANCISCO - (March 19, 2008</span></strong><span style="font-size: 10pt; font-family: 'Arial','sans-serif'">) - Solidus Networks, Inc., dba Pay By Touch, regretfully announced today that it will no longer process biometric transactions on behalf of its merchant customers and consumer membership base, as of 11:59:59PM March 19, 2008.  </span></p>
<p><span style="font-size: 10pt; font-family: 'Arial','sans-serif'">On December 14, 2007, Solidus Networks filed for U.S. bankruptcy protection under Chapter 11.  As part of the company&#8217;s restructuring, it was determined that the enterprise could no longer support the biometric authentication and payment system as it currently exists, based on lack of funding and current market conditions.  </span></p>
<p><span style="font-size: 10pt; font-family: 'Arial','sans-serif'">Other non-biometric Solidus Networks business units will continue on their current business paths.   </span></p>
<p class="MsoNormal">Solidus Networks extends its sincere gratitude to the shoppers, merchants, vendors, investors, partners, and employees who have been supporting the company&#8217;s vision since its first biometric payment transaction in 2002.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/03/20/its-official-my-old-product-is-dead/feed/</wfw:commentRss>
		</item>
		<item>
		<title>unpack!</title>
		<link>http://www.johnbaylor.org/2008/02/27/u/</link>
		<comments>http://www.johnbaylor.org/2008/02/27/u/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 07:54:16 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/02/27/u/</guid>
		<description><![CDATA[ [Update: presentation from the 4/15/2008 Ruby Meetup is now available here.]
I like reading code. Its like a novel and I want to read it cover-to-cover. Some, such as Why&#8217;s Camping framework, I struggle to comprehend. But most code that I read comes up slightly short. Like a novel with some mis-spellings, awkward phrasing or repeated [...]]]></description>
			<content:encoded><![CDATA[<p> [Update: presentation from the <a href="http://ruby.meetup.com/81/calendar/7577430/" target="_blank">4/15/2008 Ruby Meetup</a> is now available <a href="http://docs.google.com/Presentation?id=ad9wfpzzrhx_46fnbpqrgx" target="_blank">here</a>.]</p>
<p>I like reading code. Its like a novel and I want to read it cover-to-cover. Some, such as <a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" title="why not">Why&#8217;s</a> <a href="http://code.whytheluckystiff.net/camping/browser/trunk/lib/camping-unabridged.rb" title="The full source code, with many many comments.">Camping framework</a>, I struggle to comprehend. But most code that I read comes up slightly short. Like a novel with some mis-spellings, awkward phrasing or repeated analogies, I mentally mark it as &#8220;could be better&#8221;. And sometimes I really do sit down and write something better - maybe just for my own amusement but often for a useful purpose.</p>
<p>I recently had the experience of reading some code that parsed a variable-length binary data structure. This sort of thing comes up often when parsing a file format or communications protocol. Most of the code looks fairly similar because it does similar stuff: ignore one byte, read the next four as the length of the following junk, read two important bytes, ignore two more, read another four-byte length and skip past the following N bytes - ad nauseum.</p>
<p>I&#8217;ve written it in C, and it looks something like this (ignoring error conditions like getting to the end of the buffer):</p>
<pre>ptr = &amp;data;                  // start at the beginning of our data
ptr++;                        // skip junk we don't care about
UInt32 len = *(UInt32 *) ptr; // get the 4-byte length
len = ntohl(len);             // convert from network byte ordering
ptr += sizeof(UInt32);        // skip past the length we just read
ptr += len;                   // skip past the data we don't care about
UInt16 cost = *(UInt16 *)ptr; // read our important two bytes
cost = ntohs(cost);           // convert to the correct byte ordering</pre>
<p>In Ruby, this tends to be shorter due to the handy String.unpack() routine, which takes a concise format string to define how many bytes to read and what to do with them. &#8220;a3&#8243; reads 3 bytes as a string, &#8220;N&#8221; reads 4 bytes in network order, &#8220;n&#8221; reads 2 bytes in network order, etc. The code above could be rewritten in Ruby like this:</p>
<pre><span class="ident">array</span> <span class="punct">=</span> <span class="ident">data</span><span class="punct">.</span><span class="ident">unpack</span><span class="punct">(</span> <span class="punct">"</span><span class="string">a1N</span><span class="punct">")</span>        <span class="comment"># read the junk and the 4 length bytes</span>
<span class="ident">len</span> <span class="punct">=</span> <span class="ident">array</span><span class="punct">[</span><span class="number">1</span><span class="punct">]</span>                     <span class="comment"># only get the length value we care about</span>
<span class="ident">data</span> <span class="punct">=</span> <span class="ident">data</span><span class="punct">[</span><span class="number">5</span><span class="punct">..-</span><span class="number">1</span><span class="punct">]</span>                 <span class="comment"># throw away the stuff we just read</span>
<span class="ident">array</span> <span class="punct">=</span>  <span class="ident">data</span><span class="punct">.</span><span class="ident">unpack</span><span class="punct">(</span> <span class="punct">"</span><span class="string">a<span class="expr">#{len}</span>n</span><span class="punct">"</span> <span class="punct">)</span> <span class="comment"># define the length to read on the fly</span>
<span class="ident">cost</span> <span class="punct">=</span> <span class="ident">array</span><span class="punct">[</span><span class="number">1</span><span class="punct">]</span>                    <span class="comment"># get our data in its correct ordering</span>
<span class="ident">data</span> <span class="punct">=</span> <span class="ident">data</span><span class="punct">[(</span><span class="ident">len</span><span class="punct">+</span><span class="number">2</span><span class="punct">)..-</span><span class="number">1</span><span class="punct">]</span>           <span class="comment"># again, throw away what we just read</span></pre>
<p>This code works fine, but its not much more readable than the C code. A first step would be do define a string.unpack!() routine, where the &#8216;!&#8217; exclamation clues us in that it modifies the object we&#8217;re working with. In this case, the modification is to <span style="font-style: italic">eat</span> (discard) the data we just read. This shortens the code to:</p>
<pre><span class="ident">array</span> <span class="punct">=</span> <span class="ident">data</span><span class="punct">.</span><span class="ident">unpack!</span><span class="punct">(</span> <span class="punct">"</span><span class="string">a1N</span><span class="punct">")</span>       <span class="comment"># read the junk and the 4 length bytes</span>
<span class="ident">len</span> <span class="punct">=</span> <span class="ident">array</span><span class="punct">[</span><span class="number">1</span><span class="punct">]</span>                     <span class="comment"># only get the length value we care about</span>
<span class="ident">array</span> <span class="punct">=</span>  <span class="ident">data</span><span class="punct">.</span><span class="ident">unpack!</span><span class="punct">("</span><span class="string">a<span class="expr">#{len}</span>n</span><span class="punct">")</span>  <span class="comment"># define the length to read on the fly</span>
<span class="ident">cost</span> <span class="punct">=</span> <span class="ident">array</span><span class="punct">[</span><span class="number">1</span><span class="punct">]</span>                    <span class="comment"># get our data in its correct ordering</span></pre>
<p>But again, this isn&#8217;t much more readable (in my opinion) than the C code. Additionally, it doesn&#8217;t help us understand the code much better in the case where our format string is &#8220;a3Nna5&#8243; and we need to remember which item in &#8216;array&#8217; corresponds to the &#8216;n&#8217; in the string (in this case, it is array[2]). After a test iteration or two, what I finally hit upon was to encapsulate the behavior we want in a separare Unpacker class, that automatically eats the data it reads and stores the results in an internal Hash object, to map the name &#8216;len&#8217; or &#8216;cost&#8217; to the data. I also combined the format string and the resulting variable so we can clearly see the relationships. The result looks like this:</p>
<pre><span class="ident">u</span> <span class="punct">=</span> <span class="constant">Unpacker</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(</span><span class="ident">data</span><span class="punct">)</span>
<span class="ident">u</span><span class="punct">.</span><span class="ident">u!</span> <span class="punct">"</span><span class="string">a1        =&gt; unused
      N         =&gt; len</span><span class="punct">"</span>
<span class="ident">u</span><span class="punct">.</span><span class="ident">u!</span> <span class="punct">"</span><span class="string">a<span class="expr">#{u.len}</span> =&gt; unused
      n         =&gt; cost</span><span class="punct">"</span></pre>
<p>Now we can clearly see which values are ignored, which are given meaningful names, and how the format codes relate to the meaning of the data. Changing it to reflect a better understanding of the underlying data will be very easy. Note that the only reason its in two statements is to define a value for u.len before we use it - blocks of fixed-length data can be one statement.</p>
<p>The code to implement the Unpacker class is only about 30 lines of Ruby - including the string.unpack!() routine that can be reused separately.</p>
<pre><span class="keyword">class </span><span class="class">String</span>
  <span class="keyword">def </span><span class="method">unpack!</span> <span class="ident">format</span>
     <span class="ident">array</span> <span class="punct">=</span> <span class="constant">self</span><span class="punct">.</span><span class="ident">unpack</span><span class="punct">(</span><span class="ident">format</span><span class="punct">+"</span><span class="string">a*</span><span class="punct">")</span>
    <span class="constant">self</span><span class="punct">.</span><span class="ident">replace</span> <span class="ident">array</span><span class="punct">.</span><span class="ident">pop</span>
     <span class="keyword">return</span> <span class="ident">array</span>
   <span class="keyword">end</span>
<span class="keyword">end</span>
<span class="keyword">class </span><span class="class">Unpacker</span> <span class="punct">&lt;</span> <span class="constant">Hash</span>
   <span class="ident">attr_reader</span> <span class="symbol">:data</span>
 <span class="keyword">def </span><span class="method">initialize</span> <span class="ident">string</span>
     <span class="attribute">@data</span> <span class="punct">=</span> <span class="ident">string</span>
    <span class="keyword">super</span>
  <span class="keyword">end</span>
  <span class="comment"># format string is expected to have whitespace between each</span>
  <span class="comment"># "unpackCode=&gt;variableName" pairing (which can have whitespace</span>
  <span class="comment"># around the "=&gt;").  u! was picked to be short so it would</span>
  <span class="comment"># look nice, and to connote a destructive "unpack!" operation.</span>
  <span class="keyword">def </span><span class="method">u!</span> <span class="ident">format</span>
    <span class="ident">format</span><span class="punct">.</span><span class="ident">gsub</span><span class="punct">(/</span><span class="regex"><span class="escape">\s</span>*=&gt;<span class="escape">\s</span>*</span><span class="punct">/,'</span><span class="string">=&gt;</span><span class="punct">').</span><span class="ident">strip</span><span class="punct">.</span><span class="ident">split</span><span class="punct">(/</span><span class="regex"><span class="escape">\s</span>+</span><span class="punct">/).</span><span class="ident">each</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">segment</span><span class="punct">|</span>
    <span class="ident">src</span><span class="punct">,</span><span class="ident">dst</span> <span class="punct">=</span> <span class="ident">segment</span><span class="punct">.</span><span class="ident">split</span><span class="punct">(/</span><span class="regex">=&gt;</span><span class="punct">/)</span>
    <span class="constant">self</span><span class="punct">[</span><span class="ident">dst</span><span class="punct">]</span> <span class="punct">=</span> <span class="attribute">@data</span><span class="punct">.</span><span class="ident">unpack!</span><span class="punct">("</span><span class="string"><span class="expr">#{src}</span></span><span class="punct">")[</span><span class="number">0</span><span class="punct">]</span>
 <span class="keyword">end</span>
<span class="keyword">end</span>
<span class="comment"># Hash_with_Attrs - For the simplicity of using either u.len or u['len'],</span>
<span class="comment"># makes a hash appear to have members for each hash entry. Many thanks</span>
<span class="comment"># to Why_ for collecting this handy routine on his a href= RedHanded blog.</span>
<span class="comment"># Note of Caution: 'len' is fine but 'length' would not be since u.length</span>
<span class="comment"># would give the number of entries in the hash, not the just-parsed value.</span>
<span class="keyword">def </span><span class="method">method_missing</span><span class="punct">(</span><span class="ident">meth</span><span class="punct">,*</span><span class="ident">args</span><span class="punct">)</span>
  <span class="ident">meth</span> <span class="punct">=</span> <span class="ident">meth</span><span class="punct">.</span><span class="ident">id2name</span>
  <span class="keyword">if</span> <span class="ident">meth</span> <span class="punct">=~</span> <span class="punct">/</span><span class="regex">=$</span><span class="punct">/</span>
    <span class="constant">self</span><span class="punct">[</span><span class="ident">meth</span><span class="punct">[</span><span class="number">0</span><span class="punct">..-</span><span class="number">2</span><span class="punct">]]</span> <span class="punct">=</span> <span class="punct">(</span><span class="ident">args</span><span class="punct">.</span><span class="ident">length</span><span class="punct">&lt;</span><span class="number">2</span> <span class="punct">?</span> <span class="ident">args</span><span class="punct">[</span><span class="number">0</span><span class="punct">]</span> <span class="punct">:</span> <span class="ident">args</span><span class="punct">)</span>
  <span class="keyword">else</span>
    <span class="constant">self</span><span class="punct">[</span><span class="ident">meth</span><span class="punct">]</span>
  <span class="keyword">end</span>
<span class="keyword">end</span>
<span class="keyword">end</span></pre>
<p>Update: <em>An even cleaner and shorter way would be to implement a <a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language">DSL</a> as a module so the code above could look like this:</em></p>
<pre><span class="ident">a</span> <span class="number">1</span><span class="punct">,</span>    <span class="symbol">:unused</span>
<span class="constant">N</span>       <span class="symbol">:len</span>
<span class="ident">a</span> <span class="symbol">:len</span><span class="punct">,</span> <span class="symbol">:unused</span>
<span class="ident">n</span>       <span class="symbol">:cost</span></pre>
<p><em>(and yes, this is valid Ruby code)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/02/27/u/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Recommendation: The Rails Way</title>
		<link>http://www.johnbaylor.org/2008/01/29/book-recommendation-the-rails-way/</link>
		<comments>http://www.johnbaylor.org/2008/01/29/book-recommendation-the-rails-way/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 19:53:16 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/01/29/book-recommendation-the-rails-way/</guid>
		<description><![CDATA[The Rails Way is a Ruby on Rails reference book that I bought on Josh Susser&#8217;s recommendation.  I&#8217;ve actually, to my family&#8217;s dismay, been reading the darn thing instead of just referring to it like one would a, well, reference book.  A lot of Rails&#8217;isms that I had a vague idea about I now understand [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321445619" title="Amazon">The Rails Way</a> is a Ruby on Rails reference book that I bought on <a href="http://blog.hasmanythrough.com/2007/12/20/book-review-the-rails-way">Josh Susser&#8217;s recommendation</a>.  I&#8217;ve actually, to my family&#8217;s dismay, been <em>reading</em> the darn thing instead of just <em>referring</em> to it like one would a, well, reference book.  A lot of Rails&#8217;isms that I had a vague idea about I now understand with much more clarity.  It will definitely come in handy soon when I start <a href="http://www.wildpackets.com/" title="Starting February 11th, 2008">my new job</a> writing mostly RoR code!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/01/29/book-recommendation-the-rails-way/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using Ubuntu</title>
		<link>http://www.johnbaylor.org/2008/01/25/using-ubuntu/</link>
		<comments>http://www.johnbaylor.org/2008/01/25/using-ubuntu/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 22:18:07 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/01/25/using-ubuntu/</guid>
		<description><![CDATA[I&#8217;ve heard that dual-booting Ubuntu linux was easy but its really true.  I&#8217;m now running Ubuntu and it  was as easy as various blog posts have said.  The longest step in the process was defragmenting the drive before repartitioning with Ubuntu.  There are a few  issues remaining around using the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve heard that dual-booting Ubuntu linux was easy but its really true.  I&#8217;m now running Ubuntu and it  was as easy as various blog posts have said.  The longest step in the process was defragmenting the drive before repartitioning with Ubuntu.  There are a few  issues remaining around using the data on the Windows partition from Linux, but on the whole I&#8217;m very happy with the switch.</p>
<p><em>[Update 1/29/2008: the network is inconsistent.  Upon a boot or un-hibernate it may be completely incapable of finding my router - but then later it is fine. I'll continue trying to track it down... using the Windows OS!] </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/01/25/using-ubuntu/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Xkcd Titles</title>
		<link>http://www.johnbaylor.org/2008/01/14/xkcd-titles/</link>
		<comments>http://www.johnbaylor.org/2008/01/14/xkcd-titles/#comments</comments>
		<pubDate>Mon, 14 Jan 2008 20:26:04 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/01/14/xkcd-titles/</guid>
		<description><![CDATA[I&#8217;ve just noticed the geekily hilarious xkcd comic and one of the funniest aspects is that each comic has a &#8216;title&#8217; attribute (the text that pops up when you hover your mouse over the image) that is often as funny as the comic itself.  However, the length of the title often causes it to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just noticed the <a href="http://xkcd.com/249/" title="Yes, I play blindfold chess; it says so on my resume">geekily</a> <a href="http://xkcd.com/234/" title="You see, when unix gets confused by spaces, you can tell it to ignore the space by "escaping" it with a backslash which is a pun on... oh, never mind">hilarious</a> <a href="http://xkcd.com/" title="Click the link, dummy!">xkcd comic</a> and one of the funniest aspects is that each comic has a &#8216;title&#8217; attribute (the text that pops up when you hover your mouse over the image) that is often as funny as the comic itself.  However, the length of the title often causes it to be truncated in my browser (Firefox 2.x, which probably has an obscure show-entire-title setting).  Rather than arduously do a &#8216;view source&#8217; on each one (or figure out the Firefox setting), I have Ruby do it for me.  And for <em>you</em> if you want:</p>
<pre>
# xkcd.rb
# extract all the titles from xkcd comics since they
# tend to be too long to fully show in the browser

# USAGE: ruby -rubygems -rxkcd.rb -e 'Xkcd.new.show_all'

require 'open-uri'
require 'hpricot'

class Xkcd
  DOMAIN = 'http://xkcd.com/'

  def show id = 343  # 343 is the NSA/RSA one
    begin
      @hp = Hpricot.parse( open( "%s/%d/" % [DOMAIN,id.to_i] ) )
      (@hp / :img).each do |el|
        puts "%4d: %s" % [id.to_i, el[:title]] if el[:title]
      end
    rescue
    end
  end

  def show_all
    0.upto(400) do |i|
      show i
    end
  end
end</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/01/14/xkcd-titles/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Jumping on the Bandwagon</title>
		<link>http://www.johnbaylor.org/2008/01/12/jumping-on-the-bandwagon/</link>
		<comments>http://www.johnbaylor.org/2008/01/12/jumping-on-the-bandwagon/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 22:06:59 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[musings]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2008/01/12/jumping-on-the-bandwagon/</guid>
		<description><![CDATA[I just have to wonder: who were the first two people to have &#8220;died in a blogging accident&#8220;?
]]></description>
			<content:encoded><![CDATA[<p>I just have to wonder: who were the first two people to have &#8220;<a href="http://www.xkcd.com/369/" title="so very very sad">died in a blogging accident</a>&#8220;?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2008/01/12/jumping-on-the-bandwagon/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Another High-Traffic Rails Site: catalogchoice.org</title>
		<link>http://www.johnbaylor.org/2007/12/17/another-high-traffic-rails-site-catalogchoiceorg/</link>
		<comments>http://www.johnbaylor.org/2007/12/17/another-high-traffic-rails-site-catalogchoiceorg/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 01:12:46 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2007/12/17/another-high-traffic-rails-site-catalogchoiceorg/</guid>
		<description><![CDATA[Its getting a lot of traffic and seems pretty snappy:
http://www.catalogchoice.org/
So yes, Virginia, Ruby and Rails do scale.
]]></description>
			<content:encoded><![CDATA[<p>Its getting a lot of traffic and seems pretty snappy:</p>
<p><a href="http://www.catalogchoice.org/" title="catalogchoice.org">http://www.catalogchoice.org/</a></p>
<p>So yes, Virginia, Ruby and Rails do scale.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2007/12/17/another-high-traffic-rails-site-catalogchoiceorg/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Perception of Scarcity in a Climate of Fear</title>
		<link>http://www.johnbaylor.org/2007/11/28/the-perception-of-scarcity-in-a-climate-of-fear/</link>
		<comments>http://www.johnbaylor.org/2007/11/28/the-perception-of-scarcity-in-a-climate-of-fear/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 20:56:07 +0000</pubDate>
		<dc:creator>JohnB</dc:creator>
		
		<category><![CDATA[musings]]></category>

		<guid isPermaLink="false">http://www.johnbaylor.org/2007/11/28/the-perception-of-scarcity-in-a-climate-of-fear/</guid>
		<description><![CDATA[I was playing Blokus today, where competition is driven by the scarcity of space on the game board, and realized that the perception of scarcity is often more prevalent than actual scarcity - and thus we needlessly hobble ourselves by limiting things that are abundant.  Similarly, our fear that something might happen to us [...]]]></description>
			<content:encoded><![CDATA[<p>I was playing <a href="http://www.blokus.com/" title="Official Blokus site">Blokus</a> today, where competition is driven by the scarcity of space on the game board, and realized that the <em>perception</em> of scarcity is often more prevalent than <em>actual</em> scarcity - and thus we needlessly hobble ourselves by limiting things that are abundant.  Similarly, our fear that something might happen to us (crime, identity theft, terrorism, etc. - whatever monsters we see on the evening news) forces us to add locks and protections that mostly just result in making it hard for <em>us</em> to access our <em>own</em> belongings and data and websites.</p>
<p>The context for this discussion is a website (nameless, sorry) that I&#8217;m interested in working on.  The startup site, yet another type of social network, holds the promise of allowing for some very interesting and powerful interactions - but unnecessarily limits its users as it guards scarce server resources and data security.  Furthermore, and I&#8217;m going out on a limb here, I suspect that these mis-perceptions are one of the reasons  this startup has had difficulty in raising much-needed funds.  Some examples:</p>
<ul>
<li>Users are automatically logged out after a few idle minutes, with no option of changing the time period before auto-logout (or choosing &#8220;Keep me logged in&#8221; for single-user computers).  This seems a bit draconian given that there is nothing accessible on the site that couldn&#8217;t be gathered in other ways - no bank statements, social security number or mother&#8217;s maiden name.</li>
<li>A PDF document containing the public profile data for your social circle can be generated for off-line access, but only by a subset of the social circle and only for a short period of time.  I think this is intended both for security and to guard scarce resources (such as server time and bandwidth).  The former concern is misguided - anyone receiving the PDF can circumvent security by immediately sending it to bad people - which is unstoppable once you provide off-line access).  The scarcity of server time or bandwidth can be overcome by delegating it to someone else such as <a href="http://www.amazon.com/b/ref=sc_fe_l_2?ie=UTF8&amp;node=201590011&amp;no=3435361&amp;me=A36L942TSJ2AJA" title="Elastic Compute Cloud">Amazon&#8217;s ECC</a> or <a href="http://www.amazon.com/S3-AWS-home-page-Money/b/ref=sc_fe_l_2?ie=UTF8&amp;node=16427261&amp;no=3435361&amp;me=A36L942TSJ2AJA" title="Simple Storage Service">S3 services</a>.</li>
<li>New people can be invited to the social circle, but only by a small initial set of users - and those invitations expire relatively quickly.  Its unclear why this decision was made, but I suspect it was due to some perception of scarcity or security.  All it appears to do is add yet another unnecessary barrier to entry.</li>
</ul>
<p>In spite of these issues, and others, I&#8217;m still captivated by the underlying ideas that it represents and by what it could become in the future. Hopefully I can <a href="http://www.johnbaylor.org/2007/11/28/even-more-rapid-development/">rapidly prototype</a> my vision for an improved site and use it as a starting point to land a dream job.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnbaylor.org/2007/11/28/the-perception-of-scarcity-in-a-climate-of-fear/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
