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

<channel>
	<title>Programming with Poise</title>
	<atom:link href="http://blog.thetonk.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.thetonk.com</link>
	<description>On the science - and art - that is software development.</description>
	<pubDate>Wed, 03 Dec 2008 14:33:33 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multithreading</title>
		<link>http://blog.thetonk.com/archives/129</link>
		<comments>http://blog.thetonk.com/archives/129#comments</comments>
		<pubDate>Wed, 03 Dec 2008 14:33:33 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Applications]]></category>

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

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=129</guid>
		<description><![CDATA[I&#8217;d like to clear the air surrounding multicore processors.  They&#8217;re nice, yes.  They&#8217;re fancy and expensive and have a lot of (potential) horsepower.  But if we don&#8217;t utilize them properly, there&#8217;s no point.
Most applications you use daily are single threaded.  For those unfamiliar with threading, I liken a thread to a single train of thought, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to clear the air surrounding multicore processors.  They&#8217;re nice, yes.  They&#8217;re fancy and expensive and have a lot of (potential) horsepower.  But if we don&#8217;t utilize them properly, <strong>there&#8217;s no point</strong>.</p>
<p>Most applications you use daily are single threaded.  For those unfamiliar with threading, I liken a thread to a single train of thought, and a processing core to a single brain.  A single processing core (&#8221;brain&#8221;) can only work through a single thread (&#8221;train of thought&#8221;) at a time.</p>
<p>In a world of single threaded applications, multicore architectures are largely pointless.  If a single threaded application can only use a single core at a time, what use is it to have two, four, or however many cores?  Oh sure, if you have two intensely processing-intensive applications, and a dual core machine, you can run the two side by side at near* full steam, but how often does that happen?</p>
<p>We software developers need to be writing multithreaded applications, and taking advantage of the huge opportunity we have.  It doesn&#8217;t seem unreasonable to suggest that the chipmakers are moving slowly in the direction of boasting chips with many, albeit individually slower, cores.  I would not be surprised to see a 16 core CPU hit the market by the time I graduate college.  Now, balancing the number of cores with clock speeds will be an ongoing battle, I think, unless some breakthrough is made, allowing us to sidestep the current thermodynamic hurdles for a while.  It&#8217;s not uncommon for a GPU to have hundreds of smaller cores.  Look at the NVIDIA&#8217;S <a title="CUDA" href="http://www.nvidia.com/object/cuda_what_is.html" target="_blank">CUDA technology</a>.</p>
<p>This is no longer a chicken and egg problem.  The chipmakers have built us - are building us - multicore processors, and we should learn to use them properly before someone decides there&#8217;s no substantial market for the technology and bails on the idea - there are no winners in that scenario.</p>
<p>* The most common design pattern for a multicore processor is to duplicate the Registers, Control Unit, and Arithmetic Logic Unit, but for the sister cores to share the same L2 cache and bus interface.  And of course, from there on out, the rest of the machine is also (stretching the logic just a bit farther) shared by each core.  So, while you may have 200% the raw processing power, your other system resources will become bottlenecks, thereby cutting back on the overall gain.  Especially important to avoid overcrowding in this situation is the bandwidth of the main system bus.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F129&amp;title=Multithreading" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/129/feed</wfw:commentRss>
		</item>
		<item>
		<title>What NOT To Do</title>
		<link>http://blog.thetonk.com/archives/115</link>
		<comments>http://blog.thetonk.com/archives/115#comments</comments>
		<pubDate>Tue, 02 Dec 2008 17:51:14 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Development]]></category>

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=115</guid>
		<description><![CDATA[Every once in a while, during my daily activities on and about the web, I see something that stops me in my tracks.  Maybe a horrible color scheme.  Perhaps some very poorly chosen wording.  Whatever it is.  There are simply times when I sincerely wish there were a Universal encyclopedia of how NOT to behave, [...]]]></description>
			<content:encoded><![CDATA[<p>Every once in a while, during my daily activities on and about the web, I see something that stops me in my tracks.  Maybe a horrible color scheme.  Perhaps some very poorly chosen wording.  Whatever it is.  There are simply times when I sincerely wish there were a Universal encyclopedia of <strong>how NOT to behave</strong>, and I could create entries as I saw fit.</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/12/car_park_accident_large.jpg"><img class="aligncenter size-full wp-image-119" title="car_park_accident_large" src="http://blog.thetonk.com/wp-content/uploads/2008/12/car_park_accident_large.jpg" alt="" width="464" height="316" /></a></p>
<p>How could someone manage that?!  You&#8217;d think that someone literally would have to have been trying their hardest to screw up so royally, in order to achieve such mind-bogglingly astounding levels of failure.  It&#8217;s really impressive.</p>
<p>As far as web development goes, one time I saw black text on a yellow background, alternating (rather epileptically - you know what I mean) with white text on a black background.  That is how NOT to style your webpresence, whatever it is for.  Period.</p>
<p>More recently, though, I noted in a flash application, that the developers had chosen to grey out and center the text as it was entered into two input elements.  It was highly unnecessary, very unbalancing, and, more dangerously than the rest for the maintainers of the site, very distracting.  I very honestly debated entering my email address and would-be password.  I&#8217;m not sure what made me hesitate, but something about the fact that, in a form that was not centered, on a page in which nothing else was centered.  The text I was typing into these input elements, inexplicably, was centered though.  Someone got carried away.  And someone else OK&#8217;d it - that&#8217;s almost scarier.</p>
<p>Maybe I&#8217;m way off base on this one.  Maybe it was really not a big deal.  But, personally, this went down in my book of what <strong>NOT</strong> to do.</p>
<p>The centered input-elements aside.  In my own travels - of life, of the internet, on the road - a single quote has had an enormous impact on me.  I do not know whom to give credit for it&#8217;s astounding wisdom.  <strong>An intelligent man learns from his mistakes.  He is wise who learns also from the mistakes of others.</strong> When you see something so flagrantly ill-executed that it makes you instantly piteous and amazed all at once, don&#8217;t just wave it off and say &#8220;well that was dumb.&#8221;  Do yourself a favor - take a minute to breathe in the finer, more subtle details of the mishap, and learn not to do the same.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F115&amp;title=What+NOT+To+Do" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/115/feed</wfw:commentRss>
		</item>
		<item>
		<title>Gmail and Microsoft Outlook</title>
		<link>http://blog.thetonk.com/archives/102</link>
		<comments>http://blog.thetonk.com/archives/102#comments</comments>
		<pubDate>Mon, 01 Dec 2008 22:48:25 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Applications]]></category>

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

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=102</guid>
		<description><![CDATA[
I can&#8217;t get enough of Gmail.  It rules.
The conversation-based (as opposed to singular message-based) interface approach is a quite simple, yet ingenious tweak that really gives the web app a nice flow.  And, of course, it&#8217;s Google technology, so with Gmail, everything is search-able, and you never have to delete anything.  Also, the spam filter [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/12/gmail-mod.png"><img class="aligncenter size-full wp-image-110" title="gmail-mod" src="http://blog.thetonk.com/wp-content/uploads/2008/12/gmail-mod.png" alt="" width="141" height="60" /></a></p>
<p>I can&#8217;t get enough of Gmail.  It rules.</p>
<p>The conversation-based (as opposed to singular message-based) interface approach is a quite simple, yet ingenious tweak that really gives the web app a nice flow.  And, of course, it&#8217;s Google technology, so with Gmail, everything is search-able, and you never have to delete anything.  Also, the spam filter has never failed me once.</p>
<p>What could be better than my Gmail address having an interface of this caliber?  Why, having ALL of my email addresses use a similar interface.  And that&#8217;s just what Gmail lets you do.  You can use your standard Gmail account as a [POP or IMAP] client for up to five (count &#8216;em, FIVE) additional addresses.</p>
<p style="text-align: center;">
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/12/accounts-mod1.png"><img class="aligncenter size-full wp-image-105" title="accounts-mod1" src="http://blog.thetonk.com/wp-content/uploads/2008/12/accounts-mod1.png" alt="" width="500" height="89" /></a></p>
<p>Now, I&#8217;ve been using Gmail like this for about six months, and I have to say I&#8217;ve been completely satisfied in every way.  Except one.  Every once in a while, I&#8217;ll get someone ask me why my name, on mail I&#8217;ve sent, appears &#8220;On Behalf of Chris Tonkinson.&#8221;</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/12/behalf-mod1.png"><img class="aligncenter size-full wp-image-108" title="behalf-mod1" src="http://blog.thetonk.com/wp-content/uploads/2008/12/behalf-mod1.png" alt="" width="500" height="18" /></a></p>
<p>Gmail acts as does any other POP or IMAP client - so <strong>why should my outgoing mail be thus disorganized and unappealing?</strong> It turns out that when you send mail from a different address through your Gmail interface, Google automatically adds your Gmail account to the &#8220;sender&#8221; field to avoid it looking like spam.  And, in some versions of Microsoft Outlook, this can lead to the interface declaring that you are sending mail on your own behalf.</p>
<p>Perhaps you view this as proper behavior.  Perhaps not.  Either way, it seems annoying that anyone using Outlook should be encumbered by this extra verbiage.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F102&amp;title=Gmail+and+Microsoft+Outlook" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/102/feed</wfw:commentRss>
		</item>
		<item>
		<title>Fuzzy Time</title>
		<link>http://blog.thetonk.com/archives/89</link>
		<comments>http://blog.thetonk.com/archives/89#comments</comments>
		<pubDate>Mon, 17 Nov 2008 15:51:06 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Communication]]></category>

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=89</guid>
		<description><![CDATA[Recently I discovered a need (read: desire that was relatively easily fulfilled, thus necessary) for a web app to have &#8220;fuzzy time&#8221; display capabilities.  You&#8217;ve got the ironclad, all-superior, well-known, never-fail Unix timestamp (e.g. 1126935037).  Backbone of a LOT software (and for good reason), but useless for display.  You&#8217;ve got the MySQL datetime, which is [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I discovered a need (read: desire that was relatively easily fulfilled, thus necessary) for a web app to have &#8220;fuzzy time&#8221; display capabilities.  You&#8217;ve got the ironclad, all-superior, well-known, never-fail <a title="Unix Timestamp Website" href="http://www.unixtimestamp.com/index.php" target="_blank">Unix timestamp</a> (e.g. 1126935037).  Backbone of a LOT software (and for good reason), but useless for display.  You&#8217;ve got the <a title="MySQL Manual - Datetime" href="http://dev.mysql.com/doc/refman/5.0/en/datetime.html" target="_blank">MySQL datetime</a>, which is really nifty, but even for seasoned developers, can be a bit harsh on the eyes.  PHP is the winner by far.  With it&#8217;s function called <a title="PHP Documentation: date()" href="http://us3.php.net/date" target="_blank">date()</a>, you can print strings like &#8220;Monday, November 17th, 2008 at 10:21am&#8221; which is much nicer.  <strong>Isn&#8217;t abstraction wonderful?</strong></p>
<p>Let&#8217;s unpack this.  In each instance you&#8217;re moving away from a single, absolute integer, to an easier-on-the-eyes formatted string.  But why stop there?  That&#8217;s where &#8220;fuzzy time&#8221; functions come into play.  They take a given time value (timestamp, datetime, or something to that effect) and, with some very simple logic&#8230; lay it out in a much easier-to-swallow way, such as &#8220;today at 8:16am,&#8221; &#8220;yesterday around 1:30pm,&#8221; and &#8220;about two weeks ago.&#8221;  A buddy of mine used to have a fuzzy time widget for his (Fedora) desktop that ran the gambit, abstracting time as specifically as &#8220;early morning&#8221; to as generally as &#8220;early winter.&#8221;  Perhaps that&#8217;s going too far, perhaps not.  You be the judge - I thought it was pretty funny.</p>
<p>Back to the topic at hand.  I&#8217;ve always admired Facebook&#8217;s use of fuzzy time for status updates.</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/11/facebook-status.png"><img class="aligncenter size-full wp-image-90" title="facebook-status" src="http://blog.thetonk.com/wp-content/uploads/2008/11/facebook-status.png" alt="" width="296" height="32" /></a></p>
<p>At certain times of day and night (and certain levels of non-sobriety) your users can&#8217;t even parse some of the nicest date() output.  So, I went ahead and wrote a very simple PHP function to take things just one level higher up the ole&#8217; abstraction ladder.  (Note that line 2 only existed in my example script to save me typing.)</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> fuzzy_time<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #990000;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>$time<span style="color: #000099; font-weight: bold;">\&quot;</span> is: &quot;</span>;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="">'an unknown time'</span>;
  <span style="color: #009900;">&#125;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'NOW'</span><span style="color: #339933;">,</span>        <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_MINUTE'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">60</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_HOUR'</span><span style="color: #339933;">,</span>   <span style="color: #cc66cc;">3600</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_DAY'</span><span style="color: #339933;">,</span>    <span style="color: #cc66cc;">86400</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_WEEK'</span><span style="color: #339933;">,</span>   ONE_DAY<span style="color: #339933;">*</span><span style="color: #cc66cc;">7</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_MONTH'</span><span style="color: #339933;">,</span>  ONE_WEEK<span style="color: #339933;">*</span><span style="color: #cc66cc;">4</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span> <span style="">'ONE_YEAR'</span><span style="color: #339933;">,</span>   ONE_MONTH<span style="color: #339933;">*</span><span style="color: #cc66cc;">12</span> <span style="color: #009900;">&#41;</span>;
&nbsp;
  <span style="color: #666666; font-style: italic;">// sod = start of day :)</span>
  <span style="color: #000088;">$sod</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mktime</span><span style="color: #009900;">&#40;</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'m'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'d'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'Y'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #000088;">$sod_now</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mktime</span><span style="color: #009900;">&#40;</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color:#800080;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'m'</span><span style="color: #339933;">,</span> NOW <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'d'</span><span style="color: #339933;">,</span> NOW <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'Y'</span><span style="color: #339933;">,</span> NOW <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>;
&nbsp;
  <span style="color: #666666; font-style: italic;">// used to convert numbers to strings</span>
  <span style="color: #000088;">$convert</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">=&gt;</span> <span style="">'one'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">=&gt;</span> <span style="">'two'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">=&gt;</span> <span style="">'three'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4</span> <span style="color: #339933;">=&gt;</span> <span style="">'four'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5</span> <span style="color: #339933;">=&gt;</span> <span style="">'five'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">6</span> <span style="color: #339933;">=&gt;</span> <span style="">'six'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">7</span> <span style="color: #339933;">=&gt;</span> <span style="">'seven'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">8</span> <span style="color: #339933;">=&gt;</span> <span style="">'eight'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">9</span> <span style="color: #339933;">=&gt;</span> <span style="">'nine'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span> <span style="color: #339933;">=&gt;</span> <span style="">'ten'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">11</span> <span style="color: #339933;">=&gt;</span> <span style="">'eleven'</span> <span style="color: #009900;">&#41;</span>;
&nbsp;
  <span style="color: #666666; font-style: italic;">// today</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$sod_now</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$sod</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #339933;">&gt;</span> NOW<span style="color: #339933;">-</span><span style="color: #009900;">&#40;</span>ONE_MINUTE<span style="color: #339933;">*</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'just a moment ago'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #339933;">&gt;</span> NOW<span style="color: #339933;">-</span><span style="color: #009900;">&#40;</span>ONE_MINUTE<span style="color: #339933;">*</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'a few minutes ago'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time</span> <span style="color: #339933;">&gt;</span> NOW<span style="color: #339933;">-</span><span style="color: #009900;">&#40;</span>ONE_HOUR<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'less than an hour ago'</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="">'today at '</span> <span style="color: #339933;">.</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'g:ia'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// yesterday</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span> ONE_DAY <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'i'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#40;</span>ONE_MINUTE<span style="color: #339933;">+</span><span style="color: #cc66cc;">30</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$time</span> <span style="color: #339933;">+=</span> ONE_HOUR<span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="">'yesterday around '</span> <span style="color: #339933;">.</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'ga'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// within the last 5 days</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>ONE_DAY<span style="color: #339933;">*</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'l'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span>;
    <span style="color: #000088;">$hour</span> <span style="color: #339933;">=</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span> <span style="">'G'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$time</span> <span style="color: #009900;">&#41;</span>;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$hour</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">12</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$str</span> <span style="color: #339933;">.=</span> <span style="">' morning'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$hour</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">17</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$str</span> <span style="color: #339933;">.=</span> <span style="">' afternoon'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$hour</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">20</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$str</span> <span style="color: #339933;">.=</span> <span style="">' evening'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$str</span> <span style="color: #339933;">.=</span> <span style="">' night'</span>;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$str</span>;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// number of weeks (between 1 and 3)...</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>ONE_WEEK<span style="color: #339933;">*</span><span style="color:#800080;">3.5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>ONE_WEEK<span style="color: #339933;">*</span><span style="color:#800080;">1.5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'about a week ago'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>ONE_DAY<span style="color: #339933;">*</span><span style="color:#800080;">2.5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'about two weeks ago'</span>;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'about three weeks ago'</span>;
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// number of months (between 1 and 11)...</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>ONE_MONTH<span style="color: #339933;">*</span><span style="color:#800080;">11.5</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>ONE_WEEK<span style="color: #339933;">*</span><span style="color:#800080;">3.5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$m</span><span style="color: #339933;">=</span><span style="color:#800080;">0</span>; <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> ONE_YEAR; <span style="color: #000088;">$i</span> <span style="color: #339933;">+=</span> ONE_MONTH<span style="color: #339933;">,</span> <span style="color: #000088;">$m</span><span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #000088;">$i</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="">'about '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$convert</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$m</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="">' month'</span> <span style="color: #339933;">.</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$m</span><span style="color: #339933;">&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>?<span style="">'s'</span><span style="color: #339933;">:</span><span style="">''</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="">' ago'</span>;
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// number of years...</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>ONE_MONTH<span style="color: #339933;">*</span><span style="color:#800080;">11.5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">=</span><span style="color:#800080;">0</span>; <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span>ONE_YEAR<span style="color: #339933;">*</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>; <span style="color: #000088;">$i</span> <span style="color: #339933;">+=</span> ONE_YEAR<span style="color: #339933;">,</span> <span style="color: #000088;">$y</span><span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sod_now</span><span style="color: #339933;">-</span><span style="color: #000088;">$sod</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #000088;">$i</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">return</span> <span style="">'about '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$convert</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$y</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="">' year'</span> <span style="color: #339933;">.</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$y</span><span style="color: #339933;">&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>?<span style="">'s'</span><span style="color: #339933;">:</span><span style="">''</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="">' ago'</span>;
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// more than ten years...</span>
  <span style="color: #b1b100;">return</span> <span style="">'more than ten years ago'</span>;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The original base-function I used was one that I found on <a title="PHP Classes" href="http://www.phpclasses.org/" target="_blank">PHPClasses</a> by a fellow named Andrew Collington.  The code was in a class method for getting <a title="Fuzzy File Time class" href="http://www.phpclasses.org/browse/package/430.html" target="_blank">fuzzy file times</a>.  I took that code, broke it out into a function, and massaged the heck out of it.  The function takes as it&#8217;s first parameter any value accepted by the PHP function  <a title="PHP: strtotime - Manual" href="http://us3.php.net/strtotime" target="_blank">strtotime()</a>.  I chose that because of it&#8217;s impressive flexibility.  The function I ended up with only goes back to a ten-year period.  I figure, if I ever write anything that has records older than that, I can update it pretty easily.  Here&#8217;s sample output for all of the different intervals the function currently supports:</p>
<p><code><br />
"now" is: just a moment ago<br />
"-5 minutes" is: a few minutes ago<br />
"-30 minutes" is: less than an hour ago<br />
"-24 hours" is: yesterday around 10am<br />
"-48 hours" is: Saturday morning<br />
"-90 hours" is: Thursday afternoon<br />
"-1 week" is: about a week ago<br />
"-2 weeks" is: about three weeks ago<br />
"-3 weeks" is: about three weeks ago<br />
"-4 weeks" is: about one month ago<br />
"-5 weeks" is: about one month ago<br />
"-3 months" is: about three months ago<br />
"-9 months" is: about nine months ago<br />
"-13 months" is: about one year ago<br />
"-76 months" is: about six years ago<br />
"-9 years" is: about nine years ago<br />
"-26 years" is: more than ten years ago<br />
</code></p>
<p>I was suprised at how much character and youth it gave the site.  Thanks Andrew and Facebook!</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F89&amp;title=Fuzzy+Time" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/89/feed</wfw:commentRss>
		</item>
		<item>
		<title>Webstraction</title>
		<link>http://blog.thetonk.com/archives/70</link>
		<comments>http://blog.thetonk.com/archives/70#comments</comments>
		<pubDate>Thu, 30 Oct 2008 00:12:52 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Development]]></category>

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=70</guid>
		<description><![CDATA[My new foray into web development has been bolstered substantially by using jQuery for any client-side scripting needs.  However, I&#8217;ve also been using a new server-side tool in my belt.   I call it Webstraction&#8230; it&#8217;s a web development not-framework I&#8217;ve recently built.
I like the idea of web development abstractions.  That&#8217;s what CakePHP, symfony, and [...]]]></description>
			<content:encoded><![CDATA[<p>My new foray into web development has been bolstered substantially by using <a href="http://blog.thetonk.com/post/jquery-and-you-and-me" target="_blank">jQuery</a> for any client-side scripting needs.  However, I&#8217;ve also been using a new server-side tool in my belt.   I call it Webstraction&#8230; it&#8217;s a web development not-framework I&#8217;ve recently built.</p>
<p>I like the idea of web development abstractions.  That&#8217;s what <a title="CakePHP" href="http://cakephp.org/" target="_blank">CakePHP</a>, <a title="symfony" href="http://www.symfony-project.org/" target="_blank">symfony</a>, and <a title="Ruby on Rails" href="http://www.rubyonrails.org/" target="_blank">Rails</a> all are, at a very high level.  They are systems which take care of lower-level grunt work for you, and free up your time to focus on site/application design, rather than the nitty gritty technical details of the actual programming itself.  All basically serve to answer the same cry: <strong>I don&#8217;t want to write the same code more than once</strong>.  For example, header logic that checks to see if the user is logged in, footer markup that displays links at the bottom of the page, left hand navigation, etc.  You place the code for these in certain places, and then you include them where you need them.</p>
<p>Taking it a step further, many of these tools can actually automatically handle including the code for you - provided you put it in the right places, name it the right name, use it in the right fashion, and only need it in certain circumstances.  Many of these frameworks will actually write code for you, if you take the time to learn their system.</p>
<p>Now, don&#8217;t get me wrong, there is absolutely nothing wrong with learning one of these systems, and then leveraging it to quickly churn out product.  However, I take issue with them for a single reason.  Say I commit hours, weeks, whatever, to learning Rails.  To <em>really</em> learning Rails, and being beyond proficient with it.  And then I spend the time to use it for several sites.  What happens to the first site where I want to step outside of the Rails paradigm?  Do something that it doesn&#8217;t support?  Do something that goes against it&#8217;s main function?</p>
<p><strong>It breaks, or you break.</strong> Either you have to go then into the Rails core code, and start hacking it up (making upgrading to newer versions highly time-consuming, if not impossible in some cases), or you have to break down, and give up your dream (or find a compromise to make it happen).  All of these solutions are, to me, a bit unsavory.</p>
<p>What would really be nice, is a system that let you do what you do, but didn&#8217;t <strong>tell you how to go about it</strong>.  Offered you a set of tools that made you more productive, but didn&#8217;t get in your way when you wanted to go and do something non-standard.  That&#8217;s where Webstraction comes into play.  Webstraction provides standard methodologies for building web pages and accessing common code.  It is an abstraction in that, many times, the logical flow of page creation depends merely upon the existence or absence of a given file or directory.  It provides a really smooth interface for having the system automatically grab all necessary php, css, and javascript files for you.  Webstraction also has special handlers for Ajax requests.  And, most currently, I&#8217;m in the process of redeveloping it to support plug-ins (which seem, on today&#8217;s web, to be an expectation (Just look at the communities around Firefox, jQuery, and Wordpress, for instance).</p>
<p>I&#8217;ve submitted the project to SourceForge with a GNU/GPL license, and a <a title="Download Webstraction" href="https://sourceforge.net/project/showfiles.php?group_id=242515" target="_blank">recent version</a> is available for download there, however I&#8217;ve not yet completed the documentation site, nor have I migrated the Subversion repository.  More updates to follow.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F70&amp;title=Webstraction" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/70/feed</wfw:commentRss>
		</item>
		<item>
		<title>jQuery and you.  And me.</title>
		<link>http://blog.thetonk.com/archives/60</link>
		<comments>http://blog.thetonk.com/archives/60#comments</comments>
		<pubDate>Tue, 28 Oct 2008 21:02:52 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Development]]></category>

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

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=60</guid>
		<description><![CDATA[I&#8217;ve had a bit of a writers block lately.  I thought it was due to the fact that I&#8217;d been too busy developing to think up things to write.  And then I made a realization - the entire concept of a blog on computer science is to share my experiences; If I&#8217;m busy solving problems [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a bit of a writers block lately.  I thought it was due to the fact that I&#8217;d been too busy developing to think up things to write.  And then I made a realization - the entire concept of a blog on computer science is to share my experiences; If I&#8217;m busy solving problems and writing code, then, necessarily, I have blog fodder.  One of those moments where you rediscover something you already knew, in an entirely new light.</p>
<p>I&#8217;ve been getting pretty heavily into web development lately.  Wrote my own web development abstraction system (I cringe to call it a &#8220;framework&#8221; because frameworks, by definition, are restrictive, and my goal here was to do as much heavy lifting for the web developer as I could, without stepping on their toes at any point), and more recently, wrote a <a href="http://jquery.com/" target="_blank">jQuery</a> plugin for myself called Superedit.  I&#8217;ve really been loving jQuery.  Really loving it.  I would recommend it very highly if you&#8217;re looking to add any javascript to your site; <strong>jQuery makes web development a real pleasure</strong>.</p>
<p>As all of my project start, I got sidetracked.  While writing a site for the Honors Program here at my school, I decided that I&#8217;d like to make all &#8220;edit&#8221; functionality on the site happen via an edit-in-place system.</p>
<p>Take a user account page for example.  Say you want to change your contact email address.  The form might look like so:</p>
<p style="text-align: center;"><a href="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit1.png"><img class="size-medium wp-image-61 aligncenter" title="superedit1" src="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit1.png" alt="" width="258" height="40" /></a></p>
<p>And when you click on the span, I use JavaScript to turn it into an input like so:</p>
<p style="text-align: center;"><a href="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit2.png"><img class="size-medium wp-image-62 aligncenter" title="superedit2" src="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit2.png" alt="" width="292" height="33" /></a></p>
<p>You edit the content:</p>
<p style="text-align: center;"><a href="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit3.png"><img class="size-medium wp-image-63 aligncenter" title="superedit3" src="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit3.png" alt="" width="294" height="36" /></a></p>
<p>And then, on JavaScript&#8217;s blur() or change() events, the content is saved via callback, and the input is turned back into a span:</p>
<p style="text-align: center;"><a href="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit4.png"><img class="size-medium wp-image-64 aligncenter" title="superedit4" src="http://blog.thetonk.com/wp-content/uploads/2008/10/superedit4.png" alt="" width="239" height="37" /></a></p>
<p>Now, personally, I think this is one of the greatest toys Ajax has given us so far.  The ability to edit (and validate) form input without having to reload entire pages for a single element to change.  Of course, the first [working] iteration of this system spanned two disjoint JavaScript files, a php header, a php function file, and then more configuration in the markup itself.  Now I&#8217;ve got it down into two plain jQuery methods.  To initialize the element for display:</p>
<p><code>$( 'selector' ).superbox( 'initial value', callback, { options } );</code></p>
<p>And to initialize the element for editing:</p>
<p><code>$( 'selector' ).superinput( 'initial value', callback, { options } );</code></p>
<p>And the plugin handles the rest.  The only tricky part has been getting the callback to behave itself, so I&#8217;m working on getting that stable.  jQuery plugin generation is actually a pretty pleasant process.  A good primer can be found directly from <a title="jQuery documentation for authoring" href="http://docs.jquery.com/Plugins/Authoring" target="_blank">jQuery&#8217;s documentation</a>, and once you&#8217;ve gone through that, an excellent practical demonstration can be found <a title="jQuery plugin development pattern" href="http://www.learningjquery.com/2007/10/a-plugin-development-pattern" target="_blank">here</a>.</p>
<p>I&#8217;ll probably be posting again soon on Superedit when I get it stable and formally add it to the jQuery Plugin list.  If you want to add <a href="http://docs.jquery.com/Events/hover#overout" target="_blank">hover event handlers</a>, use <a href="http://docs.jquery.com/Effects/show" target="_blank">collapsible containers</a>, <a href="http://docs.jquery.com/Ajax/jQuery.get#urldatacallbacktype" target="_blank">Ajax</a>, <a href="http://docs.jquery.com/Utilities/jQuery.browser" target="_blank">browser-dependent scripting</a>, or, like me, you want to extend the already sprawling library and bend your XHTML to your will, javascript has never been easier.</p>
<p>&#8230; I think I should get paid for advertising.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me.', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F60&amp;title=jQuery+and+you.++And+me." title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/60/feed</wfw:commentRss>
		</item>
		<item>
		<title>Why Can&#8217;t We Be Friends?</title>
		<link>http://blog.thetonk.com/archives/35</link>
		<comments>http://blog.thetonk.com/archives/35#comments</comments>
		<pubDate>Mon, 27 Oct 2008 19:08:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[History]]></category>

		<category><![CDATA[Operating Systems]]></category>

		<guid isPermaLink="false">http://blog.thetonk.com/?p=35</guid>
		<description><![CDATA[If you&#8217;re looking to start a flame war, go ahead and mention that your operating system is better than another.  Do it at work.  Do it in school.  Do it on a public forum.  At lunch.  Anywhere, really.
You&#8217;ve heard all about the big three: Windows, Mac, Linux.  I know the topic has been beaten to [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re looking to start a flame war, go ahead and mention that your operating system is better than another.  Do it at work.  Do it in school.  Do it on a public forum.  At lunch.  Anywhere, really.</p>
<p>You&#8217;ve heard all about the big three: Windows, Mac, Linux.  I know the topic has been beaten to death and back again, but I feel compelled to inject a bit of objective commentary to the fray.  First, a history lesson, I should think.  In order of popularity - that is to say, market share at the time of posting.</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/09/windows_logo.jpg"><img class="size-medium wp-image-42 alignleft" src="http://blog.thetonk.com/wp-content/uploads/2008/09/windows_logo-300x218.jpg" alt="Microsoft Windows Logo" width="126" height="92" /></a></p>
<p>In 1980, an employee of Seattle Computer Products wrote a disk operating system called 86-DOS (also known as QDOS) for IBM Personal Computers using the Intel 8086.  Microsoft Corp. licensed the software, fiddled with it, and sold it as MS-DOS (&#8221;Microsoft Disk Operating System&#8221;) in 1981.  MS-DOS quickly gained popularity and market share.  In 1985, Microsoft released Windows version 1.0.  Windows continued over three major revisions until 1995.  None of which were true graphical operating systems in their own right; rather they were simply graphic shells placed over top of MS-DOS.  Windows 95, released in 1995 (surprised?) was the first true GUI OS from Microsoft.  It included a command line reminiscent (read: taken directly from) MS-DOS, however this was merely the shadow of DOS, and not a window into the heart of the operating system.  Even through to Windows Vista, traces of DOS can still be found.</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/09/apple-logo.jpg"><img class="size-medium wp-image-44 alignleft" src="http://blog.thetonk.com/wp-content/uploads/2008/09/apple-logo-256x300.jpg" alt="" width="86" height="101" /></a></p>
<p>Apple Incorporated released the Macintosh 128k in early 1984.  This system was largely a success for Apple.  The Macintosh 128k featured a mouse and keyboard to support a complete graphical user interface, which had not been done successfully before (an attempt called the Apple Lisa failed fairly quickly due to high costs and limited software availability).  A few attempts later, Apple released the Macintosh Plus in 1986 which was, arguably, one of it&#8217;s more popular systems.  System 7 was the first Mac to natively (and fully) support 32-bit addressing.  Via many significant patches and retrofitting, Mac OS made it&#8217;s way up to version 9.2.2, however the system quickly became dated, and in early 2001, Apple released Mac OS X - entirely rewritten using the Unix variant (a hybrid of Nextstep and FreeBSD) called Darwin.</p>
<p><a href="http://blog.thetonk.com/wp-content/uploads/2008/09/linux-penguin.jpg"><img class="size-medium wp-image-49 alignleft" src="http://blog.thetonk.com/wp-content/uploads/2008/09/linux-penguin-272x300.jpg" alt="" width="117" height="129" /></a></p>
<p>In the 1960&#8217;s, MIT, Bell Labs, and GE jointly worked on an experimental operating system called Multics.  The project wasn&#8217;t particularly a hit, and eventually was dropped.  However, one of it&#8217;s developers, Ken Thompson, led a team in writing a novel operating system for the PDP-7 in assembly language called Unics (yes, a play on the name Multics), which was to be a secure, efficient, time-sharing (read: multiuser) system.  Unics was later renamed Unix.  Between 1969 and 1973, the C programming language had been written by Dennis Richie et. al., and in 1973, Unix was rewritten in C.  In 1984, Richard Stallman announced the GNU free software project with the goal of organizing a unix-compatible operating system entirely comprised of free software.  Many things went well for the GNU Project.  Their microkernel, called Hurd, was not one of them.  However, in 1991, Linus Torvalds generated the monolithic Linux kernel, which was compatible with GNU software.  This springboard gave enormous popularity to both projects and arose to what is now called the &#8220;Linux&#8221; operating system, although it is more properly titled &#8220;GNU/Linux.&#8221;  Many, many, many GNU/Linux derivations exist today.</p>
<p>Now that we&#8217;re (roughly) on the same page, which one is best?  The answer is simple: <strong>they all suck</strong>.  If you&#8217;re a graphic designer, Linux will put you through torture and a half.  Once you get done with all those pesky configurations files, manage to get your devices working properly, and swallow the fact that there&#8217;s no 1-800 number in case your machine crashes, you&#8217;ll realize that Adobe Photoshop CS3 is not available for you.  If you&#8217;re a gamer, you scoff at Mac.  It&#8217;s useless.  I can&#8217;t play Team Fortress 2?  The mouse only has one button!  Where&#8217;s the registry?  And certainly, if you&#8217;re a hard-core dev, you can&#8217;t stand all of Windows&#8217; quirks.  Memory leak galore, reboots after every five minutes, security measures consume the first hour of your morning routine&#8230;. And Mac?  You can&#8217;t even tool around in certain system directories!</p>
<p>My favorite argument is the classic Windows guy vs. Mac guy.  Let me explain what I mean.</p>
<blockquote><p>Windows guy: Mac is too simple - there&#8217;s not even a right click!</p>
<p>Mac guy: Windows is too confusing!  And what the heck is a right click?</p>
<p>Windows guy: There&#8217;s no control key!</p>
<p>Mac guy: Use the apple key, dummy!</p>
<p>Windows guy: I just want to defrag my computer now and then, alright?</p>
<p>Mac guy: I just want my computer to work!</p>
<p>[<em>The Linux guy walks in, and the other two roll their eyes.</em>]</p>
<p>Mac guy: Oh jeez&#8230;.</p>
<p>Windows guy: Not HIM again&#8230;</p>
<p>Linux guy: Pffft&#8230;. Noobs.</p></blockquote>
<p>You&#8217;ve heard it - you know you have.  You&#8217;ve said it yourself, even.  What is it, I wonder, about people and their obsession over their preferred operating system?</p>
<p>I haven&#8217;t figured it out quite yet.  But let me be perfectly clear.  If an operating system does what you need it to do, how you need to do it, and within reasonable limits of timeliness, then it&#8217;s the best system <strong>for you</strong>.  And if your buddy has different needs, a different system might just be the best <strong>for him</strong>.  Even if (heaven forbid) it&#8217;s from a competing vendor. One of my personal pet peeves are those computer users who religiously claim that their choice of operating system is simply the only viable solution, and anyone who claims any differently is a heretic.</p>
<p>I just like to keep in mind a simple analogy, whenever the topic arises.  A Caravan would not be the optimal vehicle for a 17 year old student to drive back and forth to high school every day, while a Neon is certainly not the most sensical choice in transportation for a mother of 4.  (Note, however, that both are produced by Dodge because, of course, Mopar is always the best manufacturer&#8230;)</p>
<p style="text-align: center;"><a href="http://blog.thetonk.com/wp-content/uploads/2008/09/linux-mac-windows.png"><img class="size-medium wp-image-51 aligncenter" src="http://blog.thetonk.com/wp-content/uploads/2008/09/linux-mac-windows.png" alt="" width="104" height="125" /></a></p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F35&amp;title=Why+Can%26%238217%3Bt+We+Be+Friends%3F" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/35/feed</wfw:commentRss>
		</item>
		<item>
		<title>Useful Applications: Part II</title>
		<link>http://blog.thetonk.com/archives/11</link>
		<comments>http://blog.thetonk.com/archives/11#comments</comments>
		<pubDate>Sat, 09 Aug 2008 00:03:53 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Applications]]></category>

		<guid isPermaLink="false">http://blog.thetonk.com/?p=11</guid>
		<description><![CDATA[If you&#8217;re reading this post, and you&#8217;re familiar with version control software, and you&#8217;re not using it for one of your current projects, shame on you.
That having been said, for those unfamiliar with it, let me explain. Version control software is a client-server application which tracks changes in files over time. That&#8217;s it. Pretty dull, [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re reading this post, and you&#8217;re familiar with version control software, and you&#8217;re not using it for one of your current projects, <strong>shame on you</strong>.</p>
<p>That having been said, for those unfamiliar with it, let me explain. Version control software is a client-server application which tracks changes in files over time. That&#8217;s it. Pretty dull, huh? It has it&#8217;s uses. When you want to start a new project, you create what&#8217;s known as a &#8220;repository&#8221; for it under the version control system. The repository keeps track of all the files you&#8217;re dealing with. If you delete a file from your project, you tell the repository that you deleted it. If you add a file to your project, you tell it that you added a file. And when you change files, you tell it which ones you changed. And that&#8217;s really all there is to it.</p>
<p>If this seems unnecessary, that&#8217;s understandable. It did to me at first. But there are numerous advantages to be gleaned from using version control software, such as <a title="CVS Version Control" href="http://www.nongnu.org/cvs/" target="_blank">CVS</a>, or <a title="Subversion Version Control System" href="http://subversion.tigris.org/" target="_blank">Subversion</a> which is what I use. Ever have one of those dismal &#8220;oops&#8221; moments? The kind when you&#8217;re crawling around on the command line (am I the only one who still uses the CLI?) and you accidentally delete a file? Or you accidentally overwrite the wrong file? Well, them&#8217;s the breaks, I&#8217;m afraid. Unix isn&#8217;t shy. You delete a file, it&#8217;s gone. Unless you&#8217;re sitting on a nice desktop like Gnome or KDE, which has built in recycle-bin functionality, then that file is history.</p>
<p>Or is it?</p>
<p>If you&#8217;ve been using version control religiously - which I submit as the only way <em>to</em> use it - then all you have to do is open up your version control client application (I recommend <a title="Windows Subversion Client" href="http://tortoisesvn.tigris.org/" target="_blank">TortoiseSVN</a> if you&#8217;re on Windows, and <a title="Linux Subversion Client" href="http://rapidsvn.tigris.org/" target="_blank">RapidSVN</a> if you&#8217;re running Linux) and revert the dirty deed from the repository. It&#8217;s that simple. There&#8217;s always the wonderful case when you find a bit of code, and you don&#8217;t know when or why it was added, and you remove it, only to find out days later it broke another section of the application. Version control will let you bring up ANY previous version of a file that you&#8217;ve committed to the repo (that&#8217;s short for repository), at the push of a button. And with a nice file comparison tool, you can easily see what you changed, and where.</p>
<p>A good version control client will also allow you to merge files together. Say you&#8217;re working on lines 1-40 of a file, and I&#8217;m working on lines 41-100. Well modern version control systems were built with teams in mind. You commit your changes, and I&#8217;ll commit my changes. If our code changes don&#8217;t affect one another, then the two will be accepted by the repo without complaint. If they do conflict, however, you&#8217;ll be able to see what&#8217;s different where, and easily rectify the disagreement.</p>
<p><strong>If you aren&#8217;t using version control for every project, then you&#8217;re doing yourself a disservice.</strong></p>
<p>As a note, I like Subversion because of it&#8217;s ease of use. Also, Tigris (who maintains Subversion) puts out both the Windows and Linux clients I mentioned, TortoiseSVN and RapidSVN, respectively. So it&#8217;s all packaged by the same great folks. And those file comparison tools I was blathering about? TortoiseSVN has one built right in. For Linux I can recommend <a title="Linux File Comparison Tool" href="http://meld.sourceforge.net/" target="_blank">Meld</a>. There&#8217;s a small learning curve, just in getting used to how these systems work, and learning to discipline yourself into using them properly, but once you get it - I hate to use cliches - it really is one thing you&#8217;ll wonder just how you got by without.</p>
<p>For those who don&#8217;t have a server of their own, or don&#8217;t feel like tooling around with daemon services, there are free online services such as the wonderful <a title="Free Online Subversion Services" href="http://www.assembla.com/" target="_blank">Assembla</a> which provide a Subversion server to you, wherever you are.  All you need is a network connection.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F11&amp;title=Useful+Applications%3A+Part+II" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/11/feed</wfw:commentRss>
		</item>
		<item>
		<title>Useful Applications: Part I</title>
		<link>http://blog.thetonk.com/archives/9</link>
		<comments>http://blog.thetonk.com/archives/9#comments</comments>
		<pubDate>Sat, 09 Aug 2008 00:02:50 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Applications]]></category>

		<guid isPermaLink="false">http://blog.thetonk.com/?p=9</guid>
		<description><![CDATA[I&#8217;m going to start a small series on applications (or generic types of applications) that every developer should (read: really, really, really should) be using. Now of course I&#8217;m going to be able to give examples and recommendations for only the brands that I use. My goal is to introduce new types of software to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to start a small series on applications (or generic types of applications) that every developer should (read: really, really, really should) be using. Now of course I&#8217;m going to be able to give examples and recommendations for only the brands that I use. My goal is to introduce new types of software to those who have never used them, and not to wage a religious war bickering about which implementation of the technology is &#8220;best.&#8221;</p>
<p>Today, we look at automatic documentation software. What&#8217;s that… a program that writes your comments for you? Hardly. But what documentation generation software WILL do, is take the comments you write in your code, and coerce them into a more user-friendly format, usually within an html environment. And, if you pick the right software, it can do a whole lot more for you.</p>
<p>A lot of developers tend to think of documentation simply as the comments throughout their code.<br />
<code><br />
/* This is a C-style<br />
* block<br />
*comment<br />
*/<br />
# This is a shell script comment<br />
// This is a PHP-style comment<br />
</code><br />
And of course there are more. This is nice for the casual developer, personal projects, and the like. But for really large projects, for hard-core open source stuff, or for professional software, there&#8217;s something missing here. What if you&#8217;re on a team, and you want your team to know how to use an API you wrote, without worrying them with the specifics of it&#8217;s implementation? What if you just want a professional looking interface to your latest and greatest API? Perhaps you&#8217;d just like something to throw online to prove to others &#8220;Hey, I am actually working on this&#8221; without blindly tossing source code onto the interwebs. This is where documentation generation comes into play.</p>
<p>I&#8217;ve got experience with <a title="Source code documentation generator tool" href="http://www.stack.nl/%7Edimitri/doxygen/index.html" target="_blank">Doxygen</a>.  Great open source project.  For Doxygen (and it&#8217;s the same with others, such as <a title="The complete documentation solution for PHP" href="http://www.phpdoc.org/" target="_blank">phpDocumenter</a> and <a title="tool for generating API documentation" href="http://java.sun.com/j2se/javadoc/" target="_blank">Javadoc</a>), all you need to do is format your comments the proper way.  For a block-style comment, use the form:<br />
<code><br />
/**  This is a bloc comment. */<br />
</code><br />
or<br />
<code><br />
/** This is a<br />
* block comment.<br />
*/<br />
</code><br />
Inline comments (C++-style) go like this…<br />
<code><br />
/// This is a line comment, and applies to the code below it.<br />
&lt;This is some code&gt;<br />
</code><br />
And this<br />
<code><br />
&lt;This is some code&gt;  ///&lt; This comment applies to the code preceding it.<br />
</code><br />
That&#8217;s it. That&#8217;s all you have to do, and Doxygen will create documentation for you in a slew of forms, including html, xml, latex, rtf, postscript, pdf, and even Unix man page format. <a title="Example Doxygen Output" href="http://qwt.sourceforge.net/class_qwt_abstract_scale.html" target="_blank">Here</a>&#8217;s an example of Doxygen&#8217;s output. Note that all the developers of that code had to do, was to follow the commenting convention set by Doxygen. Doxygen was responsible for chewing through all of the code, writing the HTML, styles, diagrams, links, lists, tabs… everything!</p>
<p>Doxygen supports &#8220;<span style="font-family: Verdana,Arial,Helvetica;">C++, C, Java, Objective-C, Python, IDL (Corba and Microsoft flavors), Fortran, VHDL, PHP, C#, and to some extent D</span>&#8221; according to it&#8217;s website. Now like I said at the beginning, which documentation generator you use is your choice, but I&#8217;d HIGHLY recommend trying one/some out then actually using it/them. Doxygen is also capable (alongside graphviz&#8217;s dot tool) of creating images that depict call graphs, dependency trees, and the like.</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F9&amp;title=Useful+Applications%3A+Part+I" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/9/feed</wfw:commentRss>
		</item>
		<item>
		<title>Oh, a rappa!</title>
		<link>http://blog.thetonk.com/archives/7</link>
		<comments>http://blog.thetonk.com/archives/7#comments</comments>
		<pubDate>Fri, 08 Aug 2008 23:58:07 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Development]]></category>

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

		<guid isPermaLink="false">http://blog.thetonk.com/?p=7</guid>
		<description><![CDATA[That title should probably read &#8220;OO API Wrapper.&#8221;  Sorry, wrong regional dialect.  My mistake.
I&#8217;m pretty sure that anyone who has (successfully) used an API at some point will tell you that they are wonderful.  What I&#8217;m also guessing, from my admittedly limited experience, however, is that a lot of them will also [...]]]></description>
			<content:encoded><![CDATA[<p>That title should probably read &#8220;OO API Wrapper.&#8221;  Sorry, wrong regional dialect.  My mistake.</p>
<p>I&#8217;m pretty sure that anyone who has (successfully) used an <a title="Application Programming Interface" href="http://en.wikipedia.org/wiki/API" target="_blank">API</a> at some point will tell you that they are wonderful.  What I&#8217;m also guessing, from my admittedly limited experience, however, is that a lot of them will also tell you, if they&#8217;re honest, that APIs can be clumsy.  Why is that?  From the C/C++ perspective, the answer is dreadfully clear to me.  Many of the most basic and useful APIs are written in C.  Which means the large portion of them were written using a procedural paradigm.</p>
<p>You&#8217;re required to create a resource handle object (be it a pointer to some <code>struct</code> or <code>class</code> as in the MySQL and cURL C APIs, or maybe just a plain old <code>int</code>, as is the case for using POSIX threads), and then call a barrage of functions (passing the handle as a parameter each time) to manipulate it.  Straightforward enough for any reasonable person, I&#8217;d estimate.  Arbitrarily using cURL as the example, we typically see something like the following&#8230;<br />
<code><br />
CURL* handle;<br />
curl_easy_setopt( handle, CURLOPT_ERRORBUFFER, _error );<br />
curl_easy_setopt( handle, CURLOPT_FAILONERROR, true );<br />
curl_easy_setopt( handle, CURLOPT_FOLLOWLOCATION, true );<br />
curl_easy_setopt( handle, CURLOPT_HEADER, false );<br />
curl_easy_setopt( handle, CURLOPT_NOSIGNAL, 1 );<br />
curl_easy_setopt( handle, CURLOPT_AUTOREFERER, 1 );<br />
curl_easy_setopt( handle, CURLOPT_SSL_VERIFYPEER, 0 );<br />
curl_easy_setopt( handle, CURLOPT_NOPROGRESS, true );<br />
curl_easy_setopt( handle, CURLOPT_CONNECTTIMEOUT, timeout );<br />
curl_easy_setopt( handle, CURLOPT_MAXREDIRS, 5 );<br />
curl_easy_setopt( handle, CURLOPT_TIMEOUT, wait );<br />
curl_easy_setopt( handle, CURLOPT_USERAGENT, agent.c_str() );<br />
curl_easy_setopt( handle, CURLOPT_VERBOSE, false );<br />
curl_easy_perform( handle );<br />
</code></p>
<p>Not too bad, a few lines for the ability to browse the web.  Decent enough, says me.  Especially when the alternative (without the API that is) would be to use the <a title="system() function in C/C++" href="http://www.cplusplus.com/reference/clibrary/cstdlib/system.html" target="_blank">system()</a> function to pass a string like the following to the OS.<br />
<code>curl -f -v –connect-timeout 30 –data-ascii –url http://www.somesite.org/index.html</code></p>
<p>Portability?  What&#8217;s that?  Worse yet, you could use <a title="Libcurl ABI" href="http://curl.haxx.se/libcurl/abi.html" target="_blank">libcurl</a> nude.  Yikes.  And by the way, that string isn&#8217;t NEAR complete, if we&#8217;re dedicated to all of the customizations represented in the sample code.  I don&#8217;t even want to think about that.  So… looking at it this way, an API couldn&#8217;t get better.  But seriously.  What kind of self-respecting programmer doesn&#8217;t try, at least once in a while, to fix what isn&#8217;t broken?  Come on… admit it.  You&#8217;ve done it.  You did it once a long time ago and learned your lesson.  And then a situation, much like the above, arises and you said to yourself &#8220;Robert - &#8221; since that may in fact be how you address yourself - &#8220;Robert, this works… but I can do better.&#8221;  It&#8217;s natural.  Some of these APIs - as much functionality as they offer, and as wonderful as they are, just don&#8217;t cut it sometimes.  The libcurl C API, for instance, requires you to implement two callbacks, which are responsible for some very low level memory allocations and pointer dereferences.  Stuff that would make one of this new generation of upcoming greenhorn developers (who know naught but their fancy, highly abstracted, memory managed interpreters) run home and cry in the fetal position.  Jeez - I didn&#8217;t even want to do it, and I&#8217;m a fan of the low level stuff.  So who wants to do that every time you write an application that needs to rip a web page?  Who wants to do it for a SINGLE app that needs to rip just one page?</p>
<p>Not me.</p>
<p>Probably not you.</p>
<p>And, if you&#8217;re anything like me, you <strong>despise re-writing code</strong>.  One of the biggest problems with this type of code is the fact that it flies in the face of all that fancy object oriented paradigm you&#8217;re expected to exalt.  This is my idea.  For about a year now I&#8217;ve been doing this, and it&#8217;s worked <em>wonderfully</em>.  Before you use an API, think about it.  Then, take the hour to learn the API.  Test it a few times.  Be a little crazy.  Get comfortable with it.  And then take a second hour… maybe two… and write a well formed, object oriented wrapper class for the API.  Commit this class to your favorite version control system (I prefer <a title="Subversion version control system website" href="http://subversion.tigris.org/" target="_blank">Subversion</a>).  Then take the time to debug it.  Let&#8217;s face it.  Sometimes, you just have to sidetrack from your project, and I think this is a perfectly legitimate cause.</p>
<p>Let&#8217;s examine the situation.  You&#8217;ve now got a properly written class wrapping an API at your disposal.  Granted, some APIs are quite large, so this may be no trivial undertaking.  But, get the bare bones working first, and then add on as you need/want to - as with any development project.  Instead of all that code *up there* (that doesn&#8217;t include stuff like those nasty callbacks, which, using my method, you&#8217;d only have to write once) all you need is something like this:<br />
<code><br />
Curl curl;<br />
curl.setUrl( "http://some.place.dot.com/index/page.html" );<br />
curl.exec();<br />
</code></p>
<p>Oh, and the html you grabbed can be accessed via <code>curl.getResult()</code>.  Isn&#8217;t that a lot better?  Granted, you&#8217;re now probably half a day &#8220;off course.&#8221;  But guess what?  You were going to have to learn and get used to the API anyway.  You were going to have to hack your way around it&#8217;s quirks anyway.  You were going to have to write 90% of that code anyway in your actual application.  And, the real reward, the next time you have to use cURL in an application, it&#8217;s as easy as copying the wrapper class files into your project directory and using them.</p>
<p>Personally, I&#8217;ve got wrappers written for <a title="Libcurl C API" href="http://curl.haxx.se/libcurl/c/" target="_blank">cURL</a>, <a title="MySQL C API" href="http://dev.mysql.com/doc/refman/5.0/en/c.html" target="_blank">MySQL</a>, PCRE (Didn&#8217;t do much for this one, just re-packaged libpcrecpp from teh kind folks over at Google), <a title="POSIX Thread C API" href="http://www.cs.wm.edu/wmpthreads.html" target="_blank">Pthread</a>, and a C++ implementation of the MD5 algorithm I found online.   I&#8217;ve also got a wrapper on some common time functions in a class called &#8220;Timer.&#8221;   And they&#8217;re all committed to a single version control project.   When I need to add functionality, I go back, update this project with the proper code, and then, once all is copesetic, copy the updated files to whatever project needed the wrapper.</p>
<p>Now, of course, the wrapper can&#8217;t do EVERYTHING for you.   Some APIs, like cURL and Pthread, require callbacks and whatnot.   Of course, you deal with these case-by-case as appropriate for your situation.   But I&#8217;ve found that these wrappers can save a LOT of time in both the writing and debugging phases.   Also, they pay for themselves the first time you use them, if for no other reason than the fact that they keep your project code looking neat and object oriented, as it should be.   Develop them generically, and you can use the same wrappers for multiple projects (of course adapting them as needed, when needed).</p>

<span class="slashdigglicious">
<a href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Slashdot It!"><img src="http://slashdot.org/favicon.ico" height="16" width="16" alt="[Slashdot]" /></a>
<a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Digg This Story"><img src="http://digg.com/favicon.ico" width="16" height="16" alt="[Digg]" /></a>
<a href="http://reddit.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Reddit"><img src="http://reddit.com/favicon.ico" width="16" height="16" alt="[Reddit]" /></a>
<a href="http://del.icio.us/post?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Save to del.icio.us" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21', 'delicious', 'toolbar=no,width=700,height=400'); return false;"><img src="http://images.del.icio.us/static/img/delicious.small.gif" width="16" height="16" alt="[del.icio.us]" /></a>
<a href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7" title="Share on Facebook"><img src="http://www.facebook.com/favicon.ico" width="16" height="16" alt="[Facebook]" /></a>
<a href="http://technorati.com/faves?add=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7" title="Add to my Technorati Favorites"><img src="http://technorati.com/favicon.ico" width="16" height="16" alt="[Technorati]" /></a>
<a href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Save to Google Bookmarks"><img src="http://www.google.com/favicon.ico" width="16" height="16" alt="[Google]" /></a>
<a href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.thetonk.com%2Farchives%2F7&amp;title=Oh%2C+a+rappa%21" title="Stumble it!"><img src="http://www.stumbleupon.com/favicon.ico" width="16" height="16" alt="[StumbleUpon]" /></a>
</span>]]></content:encoded>
			<wfw:commentRss>http://blog.thetonk.com/archives/7/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
