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

<channel>
	<title>Perseverance Trumps Talent &#187; Tips and Tricks</title>
	<atom:link href="http://aaroncollegeman.com/category/tips-and-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaroncollegeman.com</link>
	<description></description>
	<lastBuildDate>Thu, 11 Feb 2010 22:26:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>For testing, dynamically create default values for long forms</title>
		<link>http://aaroncollegeman.com/2009/10/for-testing-dynamically-create-default-values-for-long-forms/</link>
		<comments>http://aaroncollegeman.com/2009/10/for-testing-dynamically-create-default-values-for-long-forms/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 02:25:06 +0000</pubDate>
		<dc:creator>Aaron Collegeman</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=524</guid>
		<description><![CDATA[Sometimes Web forms are long. And the longer the form, the more frequently we are plagued by details like field name duplication and making sure the field values show up in the database record  or an e-mail.  Here's a solution in JavaScript.]]></description>
			<content:encoded><![CDATA[<p>Sometimes Web forms are <em>long</em>. And the longer the form, the more frequently we are plagued by details like field name duplication and making sure the field values show up in the database record  or an e-mail.</p>
<p>So for a recent project I whipped together the following JavaScript snippet (for jQuery, of course).  The snippet does the following on page load</p>
<ul>
<li>All text fields and text areas assume a value equal to their field names</li>
<li>All select boxes take the value of their first non-empty options</li>
<li>All radio buttons get the last option checked</li>
<li>All check boxes are checked</li>
</ul>
<p>Additionally, radio buttons, select fields, and check boxes each have appended a <em>span</em> tag bearing their field name.</p>
<div class="geshi"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">;</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// text field values = text field name</span>
    $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input[type='text']&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">add</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;textarea&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>input<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      field.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span>field.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// select field value = first option with non-empty value</span>
    $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'select'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> select<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>select<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>select.<span style="color: #660066;">options</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> option<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>select.<span style="color: #660066;">selectedIndex</span> <span style="color: #339933;">&amp;&amp;</span> option.<span style="color: #660066;">value</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>
          select.<span style="color: #660066;">selectedIndex</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      field.<span style="color: #660066;">after</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&lt;span&gt;&quot;</span><span style="color: #339933;">+</span>field.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;/span&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// checkboxes = checked</span>
    $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input[type='checkbox']&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> checkbox<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>checkbox<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      checkbox.<span style="color: #660066;">checked</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      field.<span style="color: #660066;">after</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&lt;span&gt;&quot;</span><span style="color: #339933;">+</span>field.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;/span&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// radio buttons = last checked</span>
    $.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;input[type='radio']&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> radio<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>radio<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      radio.<span style="color: #660066;">checked</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      field.<span style="color: #660066;">after</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&lt;span&gt;&quot;</span><span style="color: #339933;">+</span>field.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;&lt;/span&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">;(function($) {
  $(function() {
    // text field values = text field name
    $.each($("input[type='text']").add("textarea"), function(i, input) {
      var field = $(input);
      field.val(field.attr('name'));
    });

    // select field value = first option with non-empty value
    $.each($('select'), function(i, select) {
      var field = $(select);
      $.each(select.options, function(i, option) {
        if (!select.selectedIndex &amp;&amp; option.value != '')
          select.selectedIndex = 1;
      });
      field.after("<span>"+field.attr('name')+"</span>");
    });

    // checkboxes = checked
    $.each($("input[type='checkbox']"), function(i, checkbox) {
      var field = $(checkbox);
      checkbox.checked = true;
      field.after("<span>"+field.attr('name')+"</span>");
    });

    // radio buttons = last checked
    $.each($("input[type='radio']"), function(i, radio) {
      var field = $(radio);
      radio.checked = true;
      field.after("<span>"+field.attr('name')+"</span>");
    });
  });
})(jQuery);</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>If you use this snippet in your project, there&#8217;s no need to credit me with it, but do leave a comment on the blog to let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/10/for-testing-dynamically-create-default-values-for-long-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Java 6 and Tomcat 6 on MediaTemple Virtual Dedicated Server (Linux)</title>
		<link>http://aaroncollegeman.com/2009/09/installing-java-6-and-tomcat-6-on-mediatemple-virtual-dedicated-server-linux/</link>
		<comments>http://aaroncollegeman.com/2009/09/installing-java-6-and-tomcat-6-on-mediatemple-virtual-dedicated-server-linux/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 16:11:57 +0000</pubDate>
		<dc:creator>Aaron Collegeman</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=510</guid>
		<description><![CDATA[When you gotta develop it with Java or Grails, you gotta have Tomcat. I'll talk you through it: step by step.]]></description>
			<content:encoded><![CDATA[<p><em>The instructions written here are based somewhat loosely on other blog articles I found <a href="http://www.jaysonjc.com/2008/01/16/installing-tomcat-60-on-mediatemple-dedicated-server/">here</a> and <a href="http://blog.spaceprogram.com/2004/01/starting-tomcat-as-service-on-linux.html">here</a>. At time of writing the Java JDK is at release 6 Update 16, and Tomcat is at version 6.0.20</em>.</p>
<p>There don&#8217;t seem to be many hosts out there that support Java Web application hosting. Besides, I really like <a href="http://mediatemple.net">MediaTemple</a> &#8211; their pricing is dead-on, their support is top-notch, and their attention to aesthetics puts them head-and-shoulders above every other Web host I&#8217;ve ever used.</p>
<p>But they don&#8217;t support Java. That is to say, their &#8220;(dv)&#8221; service line does not have Java installed by default. The Tomcat button in their Plesk control panel is nothing but a tease!</p>
<p>Fortunately, with full root access, we can add Tomcat to any old (dv).</p>
<h3><strong>Step 1: Enable root access</strong></h3>
<p>Start this process by enabling root access through your Account Center control panel &#8211; this is just easier than using sudo.  (If you don&#8217;t know what sudo is, this article is probably not for you.)</p>
<p><img class="alignnone size-full wp-image-511" style="border: 1px solid black;" title="root-access-and-developer-tools" src="http://aaroncollegeman.com/wp-content/uploads/2009/09/root-access-and-developer-tools.png" alt="root-access-and-developer-tools" width="600" height="259" /></p>
<h3>Step 2: Download Java</h3>
<p>First, download the latest Java JDK RPM bin file to your local computer.  You can find this download on the <a href="http://java.sun.com/javase/downloads/index.jsp">Java developers Web site</a>.  All we need here is the JDK &#8211; no Netbeans, no Java EE.  <strong>Make sure to download the file ending in .bin</strong>, otherwise you&#8217;ll have to use a package manager to install it (and I don&#8217;t know how to do that).</p>
<p>Since I&#8217;ll be using this Tomcat instance exclusively for one of my sites, I install Tomcat there.  You can install Tomcat anywhere you want, so long as you remember where you parked the Web server.</p>
<p>I like to keep my applications and their dependencies in close quarters, so I&#8217;m going to put my Java installation at <em>/var/www/vhosts/collegeman.net/subdomains/myapplication/dependencies</em>.  Upload your .bin file here with any old FTP program.</p>
<h3>Step 3: Run the Java installation</h3>
<p>Use an SSH client (I like Putty on Windows, and the native SSH client on the Mac) to jump onto your (dv). Switch to the dependencies path you created, and the change the permissions on the .bin file with the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><a href="http://www.php.net/chmod"><span style="color: #990000;">chmod</span></a> a<span style="color: #339933;">+</span>x <span style="color: #339933;">*.</span>bin</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">chmod a+x *.bin</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Now you can run the Java installation by typing the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">./</span>your<span style="color: #339933;">-</span>installation<span style="color: #339933;">-</span><a href="http://www.php.net/file"><span style="color: #990000;">file</span></a><span style="color: #339933;">.</span>bin</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">./your-installation-file.bin</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>You&#8217;ll have to hold down the <em>enter</em> key for a while to scroll through the Java license agreement.  At the end you&#8217;ll be asked to agree to the terms: type &#8216;yes&#8217; and press <em>enter</em>.  Assuming the installation completes successfully, you can move onto the next step.  (If it doesn&#8217;t complete successfully, contact <a href="http://twitter.com/kennethreitz">@kennethreitz</a>.)</p>
<h3>Step 4: Download Tomcat</h3>
<p>You can find the latest Tomcat release on the <a href="http://tomcat.apache.org/download-60.cgi">Tomcat Web site</a>.  Download the zipped tar-ball (.tgz or .tar.gz), and make sure you&#8217;re downloading the <em>Core</em>, not the <em>Deployer</em> or the <em>Source</em>. (If you happen to need the Deployer, I have no experience with this version of Tomcat &#8211; sorry.)</p>
<p>This file you should be able to download directly to your (dv) with the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">wget http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//apache.inetbridge.net/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">wget http://apache.inetbridge.net/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Make sure that when you run this command, you&#8217;re in the folder into which you&#8217;d like the download saved.</p>
<h3>Step 5: Unpack Tomcat</h3>
<p>Once the file is on your (dv), unpack the zip file with the following two commands</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">gunzip apache<span style="color: #339933;">-</span>tomcat<span style="color: #339933;">-</span>6<span style="color: #339933;">.</span>0<span style="color: #339933;">.</span>20<span style="color: #339933;">.</span>tar<span style="color: #339933;">.</span>gz
tar <span style="color: #339933;">-</span>xf apache<span style="color: #339933;">-</span>tomcat<span style="color: #339933;">-</span>6<span style="color: #339933;">.</span>0<span style="color: #339933;">.</span>20<span style="color: #339933;">.</span>tar</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">gunzip apache-tomcat-6.0.20.tar.gz
tar -xf apache-tomcat-6.0.20.tar</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>This should create an folder named <em>apache-tomcat-6.0.20</em>. I prefer to have Tomcat live in a folder simply named <em>tomcat</em>, and I prefer to have this folder be a sibling to the <em>httpdocs</em> folder in my application root.  So I move the tomcat folder there with the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">mv apache<span style="color: #339933;">-</span>tomcat<span style="color: #339933;">-</span>6<span style="color: #339933;">.</span>0<span style="color: #339933;">.</span>20<span style="color: #339933;">.</span>tar <span style="color: #339933;">/</span><span style="color: #000000; font-weight: bold;">var</span><span style="color: #339933;">/</span>www<span style="color: #339933;">/</span>vhosts<span style="color: #339933;">/</span>collegeman<span style="color: #339933;">.</span>net<span style="color: #339933;">/</span>subdomains<span style="color: #339933;">/</span>myapplication<span style="color: #339933;">/</span>tomcat</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">mv apache-tomcat-6.0.20.tar /var/www/vhosts/collegeman.net/subdomains/myapplication/tomcat</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<h3>Step 6: Test Tomcat</h3>
<p>Using my path for the example, run the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">./</span><span style="color: #000000; font-weight: bold;">var</span><span style="color: #339933;">/</span>www<span style="color: #339933;">/</span>vhosts<span style="color: #339933;">/</span>collegeman<span style="color: #339933;">.</span>net<span style="color: #339933;">/</span>subdomains<span style="color: #339933;">/</span>myapplication<span style="color: #339933;">/</span>tomcat<span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>startup<span style="color: #339933;">.</span>sh</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">./var/www/vhosts/collegeman.net/subdomains/myapplication/tomcat/bin/startup.sh</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Tomcat will report four pieces of information, boiling down to the location in which Tomcat is installed and the location in which Java is installed.  You will then be returned to the command prompt.  If you don&#8217;t see any other output from this command, you can assume Tomcat is running.  Test access to Tomcat with the following URL</p>
<p><em>http://yourdomain.com:8080</em></p>
<p>If what you see is the Tomcat Management interface, then Tomcat has been installed successfully.</p>
<h3>Step 7: Create a Tomcat service</h3>
<p>Using the command-line editor <em>vim</em>, create and open a new service file with the following command</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">vim <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span>init<span style="color: #339933;">.</span>d<span style="color: #339933;">/</span>tomcat</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">vim /etc/init.d/tomcat</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Use the following content to define the service file. Please note where you must configure this file to run on your personal (dv). Once in the editor, press the <em>i</em> key which will put the editor into insert mode.  Then paste the configuration below into the editor</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># This is the init script for starting up the
</span><span style="color: #666666; font-style: italic;">#  Jakarta Tomcat server
</span><span style="color: #666666; font-style: italic;">#
</span><span style="color: #666666; font-style: italic;"># chkconfig: 345 91 10
</span><span style="color: #666666; font-style: italic;"># description: Starts and stops the Tomcat daemon.
</span><span style="color: #666666; font-style: italic;">#
</span>
<span style="color: #666666; font-style: italic;"># Source function library.
</span><span style="color: #339933;">.</span> <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span>rc<span style="color: #339933;">.</span>d<span style="color: #339933;">/</span>init<span style="color: #339933;">.</span>d<span style="color: #339933;">/</span>functions
&nbsp;
<span style="color: #666666; font-style: italic;"># Get config.
</span><span style="color: #339933;">.</span> <span style="color: #339933;">/</span>etc<span style="color: #339933;">/</span>sysconfig<span style="color: #339933;">/</span>network
&nbsp;
<span style="color: #666666; font-style: italic;"># Check that networking is up.
</span><span style="color: #009900;">&#91;</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">${NETWORKING}</span>&quot;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;no&quot;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> <a href="http://www.php.net/exit"><span style="color: #990000;">exit</span></a> 0
&nbsp;
tomcat<span style="color: #339933;">=/</span>your<span style="color: #339933;">/</span>path<span style="color: #339933;">/</span>to<span style="color: #339933;">/</span>tomcat
startup<span style="color: #339933;">=</span><span style="color: #000088;">$tomcat</span><span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>startup<span style="color: #339933;">.</span>sh
shutdown<span style="color: #339933;">=</span><span style="color: #000088;">$tomcat</span><span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>shutdown<span style="color: #339933;">.</span>sh
export JRE_HOME<span style="color: #339933;">=/</span>usr
&nbsp;
start<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 <span style="color: #b1b100;">echo</span> <span style="color: #339933;">-</span>n $<span style="color: #0000ff;">&quot;Starting Tomcat service: &quot;</span>
 <span style="color: #666666; font-style: italic;">#daemon -c
</span> <span style="color: #000088;">$startup</span>
 RETVAL<span style="color: #339933;">=</span>$?
 <span style="color: #b1b100;">echo</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
stop<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 action $<span style="color: #0000ff;">&quot;Stopping Tomcat service: &quot;</span> <span style="color: #000088;">$shutdown</span>
 RETVAL<span style="color: #339933;">=</span>$?
 <span style="color: #b1b100;">echo</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
restart<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
 stop
 start
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># See how we were called.
</span><span style="color: #b1b100;">case</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1</span>&quot;</span> in
start<span style="color: #009900;">&#41;</span>
 start
 <span style="color: #339933;">;;</span>
stop<span style="color: #009900;">&#41;</span>
 stop
 <span style="color: #339933;">;;</span>
status<span style="color: #009900;">&#41;</span>
 <span style="color: #666666; font-style: italic;"># This doesn't work ;)
</span> status tomcat
 <span style="color: #339933;">;;</span>
restart<span style="color: #009900;">&#41;</span>
 restart
 <span style="color: #339933;">;;</span>
<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>
 <span style="color: #b1b100;">echo</span> $<span style="color: #0000ff;">&quot;Usage: <span style="color: #006699; font-weight: bold;">$0</span> {start|stop|status|restart}&quot;</span>
 <a href="http://www.php.net/exit"><span style="color: #990000;">exit</span></a> 1
esac
&nbsp;
<a href="http://www.php.net/exit"><span style="color: #990000;">exit</span></a> <span style="color: #cc66cc;">0</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;"># This is the init script for starting up the
#  Jakarta Tomcat server
#
# chkconfig: 345 91 10
# description: Starts and stops the Tomcat daemon.
#

# Source function library.
. /etc/rc.d/init.d/functions

# Get config.
. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] &amp;&amp; exit 0

tomcat=/your/path/to/tomcat
startup=$tomcat/bin/startup.sh
shutdown=$tomcat/bin/shutdown.sh
export JRE_HOME=/usr

start(){
 echo -n $"Starting Tomcat service: "
 #daemon -c
 $startup
 RETVAL=$?
 echo
}

stop(){
 action $"Stopping Tomcat service: " $shutdown
 RETVAL=$?
 echo
}

restart(){
 stop
 start
}

# See how we were called.
case "$1" in
start)
 start
 ;;
stop)
 stop
 ;;
status)
 # This doesn't work ;)
 status tomcat
 ;;
restart)
 restart
 ;;
*)
 echo $"Usage: $0 {start|stop|status|restart}"
 exit 1
esac

exit 0</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Save the file by pressing the <em>esc</em> key, entering <em>wq</em>, and the pressing <em>enter</em>.</p>
<p>Next change the permissions on your script to make the file executable</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><a href="http://www.php.net/chmod"><span style="color: #990000;">chmod</span></a> a<span style="color: #339933;">+</span>x tomcat</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">chmod a+x tomcat</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Test the script by executing the following commands</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">./</span>tomcat stop
<span style="color: #339933;">./</span>tomcat start</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">./tomcat stop
./tomcat start</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>You may get an error when you run the stop command &#8211; this is normal.  As long as you can get one full succession (starting then stopping) without errors, then you&#8217;re fine.</p>
<h3>Step 8 (Optional): Front Tomcat with Apache</h3>
<p>There are many things that you do not want Tomcat to be serving, namely static binary (like images) and text files (like CSS and scripts).  Honestly, I think this wisdom harks back to older, more inefficient times Tomcat land, still it is the best practice.  Doing so does have the additional benefit of being able to use more than one language on a single domain, e.g., PHP + Java.  So it&#8217;s not all bad.</p>
<p>As I&#8217;m pretty sure this task requires some source code compilation, I&#8217;m going to document it in a later post.</p>
<p>So do me a favor and let me know if this was useful to you.  Was it written well? Did I skip any steps? And most important, were you able to get it to work?</p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/09/installing-java-6-and-tomcat-6-on-mediatemple-virtual-dedicated-server-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working around GORM, paginating one-to-many relationships with SimpleJdbcDaoSupport (Part 1)</title>
		<link>http://aaroncollegeman.com/2009/09/working-around-gorm-paginating-one-two-many-relationships-with-simplejdbcdaosupport-part-1/</link>
		<comments>http://aaroncollegeman.com/2009/09/working-around-gorm-paginating-one-two-many-relationships-with-simplejdbcdaosupport-part-1/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 03:18:34 +0000</pubDate>
		<dc:creator>Aaron Collegeman</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=488</guid>
		<description><![CDATA[Part 1 of a two-part series in which I try to make sense of something called ORM and the way it totally screws up pagination.]]></description>
			<content:encoded><![CDATA[<p><em>This is Part 1 of a two-part series on solving a problem that I have with Grails and with ORM in general. Part 1 describes the problem; Part 2 will describe the solution. <a href="http://grails.org">Grails</a> is a first-rate Web development framework for <a href="http://groovy.codehaus.org/">Groovy</a>.  Groovy is like Python, except that underneath Groovy is Java and every Java library you ever loved.  If you&#8217;re a Java Web developer, you must give Grails a try; but if you&#8217;re a <a href="http://springframework.org">Spring Framework</a> developer, you&#8217;re in for a special treat because Grails is built on top of everything we know and love about Spring.</em></p>
<p>In the course of using Grails to develop a handful of government Web applications, I&#8217;ve discovered a small gap between my applications and my data.</p>
<p>Grails includes an incredible piece of software engineering they call <em>GORM</em>, which is short for <em>Grails Object Relational Mapping</em> and is essentially Groovy syntax for creating HibernateCriteriaBuilder instances. This is the best practice for writing database queries in Grails, and it goes something like this</p>
<div class="geshi"><pre class="groovy" style="font-family:monospace;"><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> courses <span style="color: #66cc66;">=</span> Course.<span style="color: #006600;">withCriteria</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #808080; font-style: italic;">// only approved courses, please</span>
  eq<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'approved'</span>, <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20true"><span style="color: #000000; font-weight: bold;">true</span></a><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">// in a category matching the keyword &quot;database&quot;</span>
  categories <span style="color: #66cc66;">&#123;</span>
    ilike<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'name'</span>, <span style="color: #ff0000;">'%database%'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
  <span style="color: #808080; font-style: italic;">// with offerings occurring in the future</span>
  offerings <span style="color: #66cc66;">&#123;</span>
    gt<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'starts'</span>, <span style="color: #ff0000;">'2009/09/29 21:12'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">def courses = Course.withCriteria {
  // only approved courses, please
  eq('approved', true)
  // in a category matching the keyword "database"
  categories {
    ilike('name', '%database%')
  }
  // with offerings occurring in the future
  offerings {
    gt('starts', '2009/09/29 21:12')
  }
}</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>This Groovy code is roughly equivalent to the following SQL statement</p>
<div class="geshi"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> course c
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> course_categories cc <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>cc<span style="color: #66cc66;">.</span>course_id <span style="color: #66cc66;">=</span> c<span style="color: #66cc66;">.</span>course_id<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> category cat <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>cat<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> cc<span style="color: #66cc66;">.</span>category_id<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> offering o <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#40;</span>o<span style="color: #66cc66;">.</span>course_id <span style="color: #66cc66;">=</span> c<span style="color: #66cc66;">.</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">WHERE</span>
  c<span style="color: #66cc66;">.</span>approved <span style="color: #66cc66;">=</span> 1
  <span style="color: #993333; font-weight: bold;">AND</span> LCASE<span style="color: #66cc66;">&#40;</span>cat<span style="color: #66cc66;">.</span>name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'%database%'</span>
  <span style="color: #993333; font-weight: bold;">AND</span> o<span style="color: #66cc66;">.</span>starts <span style="color: #66cc66;">&gt;</span> <span style="color: #ff0000;">'2009-09-29 21:12'</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">SELECT * FROM course c
INNER JOIN course_categories cc ON (cc.course_id = c.course_id)
INNER JOIN category cat ON (cat.id = cc.category_id)
INNER JOIN offering o ON (o.course_id = c.id)
WHERE
  c.approved = 1
  AND LCASE(cat.name) LIKE '%database%'
  AND o.starts &gt; '2009-09-29 21:12'</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Now if you don&#8217;t appreciate the difference between these two chunks of code, it&#8217;s probably because you either have no use for ORM tools (PHP developers, I&#8217;m talking to you), have never tried to use Hibernate, or have never had to write low-level data layer code with JDBC.  The rest of you are probably thinking, &#8220;Man, that&#8217;s pretty frickin&#8217; cool.&#8221; Because it is.</p>
<p>As I&#8217;ve experienced it, there&#8217;s only one problem with the GORM way, and it&#8217;s actually a problem with the ORM way in general.</p>
<p>In our example above we reference three domain objects: Course, Category, and Offering. For the sake of our example, we will assume that there are one-to-many relationships between Courses and Categories, as well as between Courses and Offerings.  That means for every one Course in the system, we&#8217;ll have zero, one, or more than one Offerings related to it.</p>
<p>Relationships like these are exactly what RDBMSs and ORM are all about: taking flat relationships and turning them into hierarchies of objects.  The problem is that when we rely on these relationships for the purpose of querying data, we almost always introduce duplication into our result set.</p>
<p>Imagine a set of data in which there are two courses, each with two related offerings.  Imagine that all of these records satisfy our query above.  The result set for our SQL query would look something like this</p>
<div class="geshi"><pre class="plain" style="font-family:monospace;">COURSE.ID NAME             OFFERING.ID STARTS     ENDS
1         Tuning Your SQL  1           2009/10/26 2009/10/26
1         Tuning Your SQL  2           2010/01/01 2010/01/04
2         Hiring Good Help 3           2009/11/04 2009/11/05
2         Hiring Good Help 4           2009/12/06 2009/12/07</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">COURSE.ID NAME             OFFERING.ID STARTS     ENDS
1         Tuning Your SQL  1           2009/10/26 2009/10/26
1         Tuning Your SQL  2           2010/01/01 2010/01/04
2         Hiring Good Help 3           2009/11/04 2009/11/05
2         Hiring Good Help 4           2009/12/06 2009/12/07</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Take note of the duplication: two instances of a course record for each instance of the corresponding offering record. The problem has the potential to get worse when we introduce categories.</p>
<div class="geshi"><pre class="plain" style="font-family:monospace;">COURSE.ID NAME             CATEGORY            OFFERING.ID STARTS     ENDS
1         Tuning Your SQL  Database Management 1           2009/10/26 2009/10/26
1         Tuning Your SQL  Database Management 2           2010/01/01 2010/01/04
1         Tuning Your SQL  Databases, General  1           2009/10/26 2009/10/26
1         Tuning Your SQL  Databases, General  2           2010/01/01 2010/01/04
2         Hiring Good Help Database Personnel  3           2009/11/04 2009/11/05
2         Hiring Good Help Database Personnel  4           2009/12/06 2009/12/07</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">COURSE.ID NAME             CATEGORY            OFFERING.ID STARTS     ENDS
1         Tuning Your SQL  Database Management 1           2009/10/26 2009/10/26
1         Tuning Your SQL  Database Management 2           2010/01/01 2010/01/04
1         Tuning Your SQL  Databases, General  1           2009/10/26 2009/10/26
1         Tuning Your SQL  Databases, General  2           2010/01/01 2010/01/04
2         Hiring Good Help Database Personnel  3           2009/11/04 2009/11/05
2         Hiring Good Help Database Personnel  4           2009/12/06 2009/12/07</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Where once there were two copies of Course #1 now there are four!</p>
<p>Now, in most circumstances, this really isn&#8217;t an issue. That&#8217;s right. I said <em>isn&#8217;t</em> an issue.</p>
<p>GORM and Hibernate both provide the means for eliminating this duplication at object instantiation, and it&#8217;s called <em>distinct. </em>All we have to do to implement this feature is change one line in our original GORM query (the first one):</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">def courses <span style="color: #339933;">=</span> Course<span style="color: #339933;">.</span>createCriteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>listDistinct <span style="color: #009900;">&#123;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">def courses = Course.createCriteria().listDistinct {</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Now if we were to loop over the contents of <em>courses</em>, we would find two objects instead of six: one for each unique Course is our result set.</p>
<p>One very common use case for Web applications is large result set pagination. While our own example result set doesn&#8217;t warrant pagination, one containing a thousand relationships between hundreds of courses, offerings, and categories, certainly would.</p>
<p>GORM includes two query features for pagination: <em>firstResult</em>, which should be a positive integer indicating the first row to return, and <em>maxResults</em>, which should be a positive integer indicating the page size.  When woven into our original GORM query, the code now looks like the following</p>
<div class="geshi"><pre class="groovy" style="font-family:monospace;"><a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> courses <span style="color: #66cc66;">=</span> Course.<span style="color: #006600;">createCriteria</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">listDistinct</span> <span style="color: #66cc66;">&#123;</span>
  <span style="color: #808080; font-style: italic;">// only approved courses, please</span>
  eq<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'approved'</span>, <a href="http://www.google.de/search?q=site%3Adocs.codehaus.org/%20true"><span style="color: #000000; font-weight: bold;">true</span></a><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">// in a category matching the keyword &quot;database&quot;</span>
  categories <span style="color: #66cc66;">&#123;</span>
    ilike<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'name'</span>, <span style="color: #ff0000;">'%database%'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
  <span style="color: #808080; font-style: italic;">// with offerings occurring in the future</span>
  offerings <span style="color: #66cc66;">&#123;</span>
    gt<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'starts'</span>, <span style="color: #ff0000;">'2009/09/29 21:12'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#125;</span>
  firstResult<span style="color: #66cc66;">&#40;</span>x<span style="color: #66cc66;">&#41;</span>
  maxResults<span style="color: #66cc66;">&#40;</span>y<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#125;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">def courses = Course.createCriteria().listDistinct {
  // only approved courses, please
  eq('approved', true)
  // in a category matching the keyword "database"
  categories {
    ilike('name', '%database%')
  }
  // with offerings occurring in the future
  offerings {
    gt('starts', '2009/09/29 21:12')
  }
  firstResult(x)
  maxResults(y)
}</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>So imagine a version of our result set that when raw contains 100 records.  That&#8217;s 100 instances of relationships between Courses and Categories, and Courses and Offerings.  Irrespective of the total number of distinct Courses, we decide that we&#8217;d like to paginate our result set 10 records at a time.  And this is where somewhere in the beautiful stack that is Grails, something goes ker-splat!</p>
<p><em>Check back soon for Part 2!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/09/working-around-gorm-paginating-one-two-many-relationships-with-simplejdbcdaosupport-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spotlight: go to Hell</title>
		<link>http://aaroncollegeman.com/2009/08/spotlight-go-to-hell/</link>
		<comments>http://aaroncollegeman.com/2009/08/spotlight-go-to-hell/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 00:18:50 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=381</guid>
		<description><![CDATA[Ever since I bought my MacBook I&#8217;ve been using QuickSilver instead of Spotlight.  I don&#8217;t use QuickSilver in any way that I wasn&#8217;t able to use Spotlight (still need to cache in on that training @scottspriggs said he would give me).  But I prefer QuickSilver&#8217;s interface, and the speed with which it identifies exactly what [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since I bought my MacBook I&#8217;ve been using <a href="http://blacktree.com/?quicksilver">QuickSilver</a> instead of Spotlight.  I don&#8217;t use QuickSilver in any way that I wasn&#8217;t able to use Spotlight (still need to cache in on that training <a href="http://twitter.com/scottspriggs">@scottspriggs</a> said he would give me).  But I prefer QuickSilver&#8217;s interface, and the speed with which it identifies exactly what I&#8217;m trying to access.</p>
<p>Until tonight, Spotlight had been allowed to continue running quietly in the background.  For some reason unknown to me, tonight Spotlight decided to start indexing the terabyte-or-so of backup data I have on my Drobo.  Stupid Spotlight: the CPU is reserved for programs that matter.</p>
<p>So I tried all of the GUI tricks for making Spotlight stop. There&#8217;s really only one: adding the Drobo to the Privacy list in Spotlight Preferences.  Needless to say, if that had worked, I wouldn&#8217;t be blathering about it here.</p>
<p>It didn&#8217;t work.  Fifteen minutes later, I discovered that this is another one of those OSX features that have to be disabled through a command line procedure:</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">sudo launchctl unload <span style="color: #339933;">-</span>w <span style="color: #339933;">/</span><a href="http://www.php.net/system"><span style="color: #990000;">System</span></a><span style="color: #339933;">/</span>Library<span style="color: #339933;">/</span>LaunchDaemons<span style="color: #339933;">/</span>com<span style="color: #339933;">.</span>apple<span style="color: #339933;">.</span>metadata<span style="color: #339933;">.</span>mds<span style="color: #339933;">.</span>plist</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>And just like that: Spotlight was no more.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/08/spotlight-go-to-hell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change date formats in Joomla content</title>
		<link>http://aaroncollegeman.com/2009/03/change-date-formats-in-joomla-content/</link>
		<comments>http://aaroncollegeman.com/2009/03/change-date-formats-in-joomla-content/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 21:58:14 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=298</guid>
		<description><![CDATA[This was making me insane, but I learned a couple of things about Joomla in the process.
So I&#8217;m using the Blog layout for a Category of Joomla content. (Yes, I realize Wordpress is a better tool for blogging.  Stay with me here.)
By default, the dates displayed with each article title look like this:
Sunday, 29 March, [...]]]></description>
			<content:encoded><![CDATA[<p>This was making me insane, but I learned a couple of things about Joomla in the process.</p>
<p>So I&#8217;m using the Blog layout for a Category of Joomla content. (Yes, I realize Wordpress is a better tool for blogging.  Stay with me here.)</p>
<p>By default, the dates displayed with each article title look like this:</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">Sunday<span style="color: #339933;">,</span> <span style="color: #cc66cc;">29</span> March<span style="color: #339933;">,</span> <span style="color: #cc66cc;">2009</span> <span style="color: #cc66cc;">17</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">44</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">Sunday, 29 March, 2009 17:44</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>I mean, that&#8217;s great: if you&#8217;re British.</p>
<p>The first thing that baffled me was the composition of the templates in <em>com_content</em>.  Looks like this (in com_content/views/category/blog.php)</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$z</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$z</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'num_columns'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$z</span> <span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$z</span> <span style="color: #339933;">&gt;</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$divider</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot; column_separator&quot;</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
	params<span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'num_intro_articles'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'num_columns'</span><span style="color: #009900;">&#41;</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: #009900;">&#41;</span> <span style="color: #339933;">:</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">total</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$numIntroArticles</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span> <span style="color: #339933;">=&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'item'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$i</span> <span style="color: #339933;">++;</span>
	<span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">endfor</span><span style="color: #339933;">;</span> </pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">for ($z = 0; $z &lt; $this-&gt;params-&gt;get('num_columns'); $z ++) :
	if ($z &gt; 0) : $divider = " column_separator"; endif; ?&gt;

	params-&gt;get('num_intro_articles') / $this-&gt;params-&gt;get('num_columns')); $y ++) :
	if ($i &lt; $this-&gt;total &amp;&amp; $i &lt; ($numIntroArticles)) :
		$this-&gt;item =&amp; $this-&gt;getItem($i, $this-&gt;params);
		echo $this-&gt;loadTemplate('item');
		$i ++;
	endif;
endfor; </textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>For the life of me, I couldn&#8217;t figure out what <em>$this-&gt;loadTemplate(&#8217;item&#8217;) </em>did (mostly because the patTemplate API is buried beneath the Joomla API, and because PHP toolsets just aren&#8217;t sophisticated enough yet. But I digress).</p>
<p>Google revealed that when you call <em>$this-&gt;loadTemplate(String) </em>from within a Joomla template file, the presentation framework looks for a file named &#8220;&lt;template&gt;_&lt;name&gt;.php&#8221; where &lt;template&gt; is the name of the current template file (in this case, &#8220;blog&#8221;) and &lt;name&gt; is the value passed to the <em>loadTemplate</em> method.</p>
<p>So then, in com_content/views/category/blog_item.php, I found this bit of obscurity</p>
<div class="geshi"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> JHTML<span style="color: #339933;">::</span>_<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'date'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">created</span><span style="color: #339933;">,</span> JText<span style="color: #339933;">::</span>_<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DATE_FORMAT_LC2'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">echo JHTML::_('date', $this-&gt;item-&gt;created, JText::_('DATE_FORMAT_LC2'));</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Fortunately, this one was easier to follow, but in the end, I still had to use Google to discover that DATE_FORMAT_LC2 is a reference from Joomla&#8217;s implementation of internationalization. Internationalization is configured with the files stored in the <em>language</em> folder. At this point, the correct way to fix my problem would have been to create a new language zone (e.g., en-US), but instead I decided just to amend the existing source.</p>
<p>In the file language/en-GB/en-GB.ini, you&#8217;ll find a series of definitions looking something like this</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">DATE_FORMAT_LC<span style="color: #339933;">=%</span>A<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>d <span style="color: #339933;">%</span>B <span style="color: #339933;">%</span>Y
DATE_FORMAT_LC1<span style="color: #339933;">=%</span>A<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>d <span style="color: #339933;">%</span>B <span style="color: #339933;">%</span>Y
DATE_FORMAT_LC2<span style="color: #339933;">=%</span>A<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>d <span style="color: #339933;">%</span>B <span style="color: #339933;">%</span>Y <span style="color: #339933;">%</span>H<span style="color: #339933;">:%</span>M
DATE_FORMAT_LC2<span style="color: #339933;">=%</span>B <span style="color: #339933;">%</span>d<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>Y
DATE_FORMAT_LC3<span style="color: #339933;">=%</span>d <span style="color: #339933;">%</span>B <span style="color: #339933;">%</span>Y
DATE_FORMAT_LC4<span style="color: #339933;">=%</span>d<span style="color: #339933;">.%</span>m<span style="color: #339933;">.%</span>y
DATE_FORMAT_JS1<span style="color: #339933;">=</span>y<span style="color: #339933;">-</span>m<span style="color: #339933;">-</span>d</pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">DATE_FORMAT_LC=%A, %d %B %Y
DATE_FORMAT_LC1=%A, %d %B %Y
DATE_FORMAT_LC2=%A, %d %B %Y %H:%M
DATE_FORMAT_LC2=%B %d, %Y
DATE_FORMAT_LC3=%d %B %Y
DATE_FORMAT_LC4=%d.%m.%y
DATE_FORMAT_JS1=y-m-d</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Theoretically, all of the core components of the Joomla framework use these definitions for their date formats, and the formats correspond to the PHP <a href="http://us2.php.net/manual/en/function.date.php">date</a> function.  Change these settings to whatever you&#8217;d like, and enjoy the convenience of seeing your change applied globally.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/03/change-date-formats-in-joomla-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing bug-free code, and other modern myths</title>
		<link>http://aaroncollegeman.com/2009/03/writing-bug-free-code-and-other-modern-myths/</link>
		<comments>http://aaroncollegeman.com/2009/03/writing-bug-free-code-and-other-modern-myths/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 04:45:17 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=295</guid>
		<description><![CDATA[It&#8217;s almost perfect.
That project you&#8217;ve been working on for months and months or maybe even years is almost into the test system.
You&#8217;re running down your checklist of features, painstakingly assembled from a series of torn legal pads, post-it notes, and napkins.   So far, everything is perfect.
Then, at 7:21 PM, you arrive back in the [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost perfect.</p>
<p>That project you&#8217;ve been working on for months and months or maybe even years is almost into the <em>test </em>system.</p>
<p>You&#8217;re running down your checklist of features, painstakingly assembled from a series of torn legal pads, post-it notes, and napkins.   So far, everything is perfect.</p>
<p>Then, at 7:21 PM, you arrive back in the same old tired reality.</p>
<p>&#8220;I found another bug.&#8221;  Doh!</p>
<p>There are a number of problems with this scenario.</p>
<p><strong>First, why have you been working on your project for months without putting something in your clients&#8217; hands?</strong></p>
<p>There&#8217;s a great book written by 37 Signals titled <a href="http://gettingreal.37signals.com/">Getting Real</a>.  <em>Getting real</em> means <em>having the right team</em>: small and organized, with a developer, a designer, and a generalist to pull it all together.  Getting real means <em>staying focused</em>: keeping the feature list small, and having a technical non-developer on-hand to establish completion.</p>
<p>But most importantly, getting real means <em>getting real</em>: drop the wireframes; forget about state diagrams; put fingers to keyboard and <em>turn the idea into a product that can be used</em>.</p>
<p>If you&#8217;ve never heard of or read the book yourself, <a href="http://gettingreal.37signals.com/">check it out</a>.</p>
<p><strong>Second, if your checklist of features requires anything larger than a single piece of legal paper, then you have too many features planned, especially if you&#8217;re only on your first release. </strong></p>
<p>At <a href="http://clutch-inc.com">Clutch</a> I&#8217;m working on a piece of software that has exactly fifty business rules.  Fifty rules is <em>a lot of rules</em>, but I&#8217;ve been doing this Web development stuff for a while.  I&#8217;m <em>seasoned</em>.  Plus, I&#8217;ve got people working with me: someone to do the straight-forward, <em>fingers to the keyboard </em>kind of work; and a crackshot designer to make it look good.</p>
<p>Feature creep begins innocently enough. &#8220;Instead of storing the shopping cart in the session, I&#8217;ll start storing it in the database.&#8221;</p>
<p>Before you know it, you&#8217;re worrying about things like <em>scalability</em>, <em>modularity </em>or <em>code reuse</em>, and <em>efficiency</em>;<em> </em>and you&#8217;re no longer <em>getting real</em>.  Instead, you&#8217;re tackling all those potential problems before honing any of those fifty business rules; and believe you me: those fifty business rules aren&#8217;t going to go away: fifty business rules is <em>a lot of rules</em>.</p>
<p>Keep it lean, dude.  Make it better later.</p>
<p><strong>Third, why are you testing your own software?</strong></p>
<p>Newbie mistake numero uno: you can&#8217;t test your own business logic.</p>
<p>It made sense in your head.  It made sense when you coded it.  It makes sense everytime you push that little button, the application turns green, and you get a record in the database.</p>
<p>But when your client pushes that <em>other</em> button, your application turns red, and the database disappears.  Suddenly, things stop making sense.</p>
<p><em>The only test you should do yourself is to push the play button on your unit testing code</em>.</p>
<p>Unit testing code?  As the name implies, unit testing code is code that tests other code in <em>units</em> or <em>modules</em>.</p>
<p>Say you have an application that allows its users to shop for widgets.  The phrase &#8220;shop for widgets&#8221; implies all sorts of <em>micro processes</em>: loading records from the database, routing user requests, validating input, storing new records, sending e-mail, handling errors &#8211; the list goes on and on.</p>
<p>Each one of those micro processes is or is composed of <em>units of work</em>; and if you&#8217;re coding the <em>sane way</em>, you&#8217;re testing each one of those units independently of the whole.</p>
<p>It&#8217;s much easier to detect a faulty feature in a data access object when the test doesn&#8217;t involve the Web application interface &#8211; trust me.</p>
<p>These days, you can find a unit testing framework for any platform: <a href="http://www.junit.org/">JUnit</a> for Java, <a href="http://www.simpletest.org/">SimpleTest</a> for PHP, and <a href="http://www.nunit.org/index.php">NUnit</a> on the .NET enterprise.  I can&#8217;t vouch for NUnit, but JUnit and SimpleTest are absolutely indispensible tools in my toolkit.</p>
<p>Once you&#8217;re unit testing, you might as well start doing <em>test-driven development</em>.  <em>Test-driven development</em> is development that is driven by tests.</p>
<p>First, you write some unit testing code that relies on a valid business process, e.g.,</p>
<div class="geshi"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> void testMaximum<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;The maximum of 4 and 2 is 4.&quot;</span><span style="color: #339933;">,</span> Math<span style="color: #339933;">.</span><a href="http://www.php.net/max"><span style="color: #990000;">max</span></a><span style="color: #009900;">&#40;</span>2<span style="color: #339933;">,</span> 4<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> 4<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre><textarea onfocus="jQuery(this).select();" onblur="jQuery(this).hide().prev().show();" style="display:none;">    public void testMaximum() {
        assertEquals("The maximum of 4 and 2 is 4.", Math.max(2, 4), 4);
    }</textarea><a class="clipboard" href="javascript:;" onclick="jQuery(window).scrollTo(jQuery(this).prev().show().focus().prev().hide().parent(), 500);">copy code</a></div>
<p>Then, you write the code that enacts the business process.  You go back and run the test, and if the test passes, then you&#8217;re free to move onto the business rule.</p>
<p>This formula for composing code puts the application&#8217;s story ahead of the pages on which it&#8217;s written.  If you focus first on what the application is supposed to do, getting it there will feel more like <em>winning the game</em> than <em>fighting an endless battle with yourself</em>.</p>
<p><strong>Fourth, why are you working at 7:21 PM?</strong></p>
<p>Well, perhaps it&#8217;s for the same reason that I&#8217;m writing this blog article at 10:49 PM: sometimes the creative juices just flow faster in the evening.</p>
<p>But if you&#8217;re anything like me, you&#8217;ve also probably been at it since 8 AM; and even though you <em>feel </em>like the code is flowing easily, the reality is much more stark.</p>
<p><em>You&#8217;re creating tomorrow&#8217;s messes, today.  Hooray for your stamina!<br />
</em></p>
<p>Always remember the <em>rule of thirds</em>: one-third of your life will be spent asleep (if you&#8217;re <em>lucky</em>); one-third of your life will be spent <em>at work</em>; and the other third should be spent <em>eating, doing things purely for fun (like sex), creating, </em>or <em>resting (sleeping some more, maybe?)</em>.</p>
<p>As developers who love to develop, we find it easy to be lulled into a sense of being creative through our work &#8211; that our work itself is part of that <em>creating</em> <em>time </em>belonging to the third-third of our lives.</p>
<p>Get <em>real</em>: work is <em>work</em>.  And though it ain&#8217;t like diggin&#8217; ditches, programming is hard on the body.  Checked your posture lately?  How do your eyes feel right now?  Can you pinch an inch of fat around your midsection?  That&#8217;s what I thought.   Believe me, I&#8217;m right there with you.</p>
<p>So the next time you look down and realize that you should have left work thirty minutes ago, try to remember the <em>fifth</em> thing that&#8217;s wrong with our shared scenario.</p>
<p><strong>Your code will never be perfect.</strong></p>
<p>It is for this reason that <a href="http://www.randsinrepose.com">Rands</a> invented the <a href="http://www.randsinrepose.com/archives/2009/01/18/the_larry_test.html">Larry Test</a>.   Because Larry would never have been done, unless his test told him so.</p>
<p>As Rands explains, when left to his own devices, a developer&#8217;s job is never done.  We refine, recode, refactor, reevaluate, and recode some more, until we think we&#8217;ve achieved perfection.</p>
<p>But perfection <em>never </em>comes.</p>
<p>Perfection <em>doesn&#8217;t exist</em> in our world any more than it does in the world outside the CPU.  At a high level like JavaScript, everything is ones and zeros.  With enough effort, you can probably herd all of those ones and zeros into a straight line, write a program to interpret them, and prevent cross-site scripting attacks along the way.  Perfection <em>seems </em>achievable.</p>
<p>But were you aware that when you depress a button on an electronic device, there&#8217;s a program somewhere, patiently and carefully waiting for the electrical switch to stop shaking wildly back and forth?  Waiting patiently to take the final reading, and establish a one or a zero?</p>
<p>What happens if that one or zero never comes?  It is, after all, nothing more than electricity.  A stray magnet, and EMP of one variety or another, a lighting bolt.  Any one of these will drive the voltage right of the charts, leaving that little program with nothing to measure and no way to recover from the failure.</p>
<p>Every single piece of code we write rests atop a stack of hardware: an inescapable electrical reality, confining our <em>perfect</em> programs to a dimension of physical randomness.</p>
<p>At the end of the day, fifty lines of code are probably just as efficient as five.  It&#8217;s only when your user base increases by an order of magnitude that the game becomes something different.</p>
<p>Consider how long its been since Twitter rolled out a new feature.   Surely they have some good ideas on hand.   But the developers at Twitter are busy doing one thing and one thing only: scaling their core feature set to 100,000 new users a month.  Their idea of perfection is a Twitter than can stand the test of the 2008 elections, or the next Super Bowl, or a natural disaster of Katrina proportions.</p>
<p>&#8212;</p>
<p>So, the next time you embark on a new development project, remember these basics:</p>
<ul>
<li>Get real as soon as possible: make it your mission to create a physical manifestation of your ideas</li>
<li>Keep the feature list small and allow your project to evolve iteratively</li>
<li>Do <em>not </em>test your own software: start with code that expresses your business processes and work backward</li>
<li>Go home at the end of the day: exercise, eat well, and invest your free time in another human being</li>
<li>And for the love of peat, stop chasing perfection because it doesn&#8217;t exist; and if you keep pursuing it, neither will you.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/03/writing-bug-free-code-and-other-modern-myths/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gmail filters: NOT from</title>
		<link>http://aaroncollegeman.com/2009/02/gmail-filters-not-from/</link>
		<comments>http://aaroncollegeman.com/2009/02/gmail-filters-not-from/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 00:59:47 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[gmail]]></category>

		<guid isPermaLink="false">http://aaroncollegeman.com/?p=256</guid>
		<description><![CDATA[Lately I&#8217;ve been using the Gmail Labs &#8220;Multiple Inboxes&#8221; feature.  This is really useful because it lets me turn my Gmail inbox into a heads-up-display for different kinds of e-mail.  For now, I&#8217;m using this for only two things: separating out unread from read, and separating out the influx of conservative commentary (forwarded to me [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been using the Gmail Labs &#8220;Multiple Inboxes&#8221; feature.  This is really useful because it lets me turn my Gmail inbox into a heads-up-display for different kinds of e-mail.  For now, I&#8217;m using this for only two things: separating out unread from read, and separating out the influx of conservative commentary (forwarded to me by a friend from Chicago, go figure).  At the bottom then is my regular inbox.</p>
<p>The problem with this has been that the stuff from Chicago, when unread, shows up in all three places.  What I wanted to do was separate unread, from unread Chicago e-mail, from everything else.  Each inbox in multiple inbox mode is driven by a filter, a feature of Gmail that is really broad and useful.</p>
<p>In filters, the search field acts more like a command line than a simple keyword matching tool.  For instance, if you prefix an e-mail address or name with the keyword <em>from:</em>, you&#8217;ll see only messages from that person.  This is different from just searching for the name or e-mail address by itself, whereby you&#8217;ll get address, subject, and body keyword matches. There are other prefixes and special keywords too, like <em>to:</em> and <em>subject:</em>, and also <em>is:unread</em>, <em>is:read</em>, and <em>has:attachment</em>.</p>
<p>But what I wanted to do was filter out everything unread <em>and</em> from Chicago.  To do this, I needed a <em>not</em>, as in <em>show me everything that is unread, but not from Chicago</em>. Gmail supports and documents the use of the word <em>NOT</em> in keyword searches, e.g., <em>foo</em> <em>AND bar NOT foobar</em>, but this doesn&#8217;t work with the prefixes listed above.  It took a bit of guess and check to figure it out, but eventually I discovered this solution: <strong><em>is:unread from:!email@domain.com</em></strong>.  (Take note of the exclamation point.)</p>
<p>This solution works perfectly, proving once again just how superior Gmail is to all other Web-based e-mail, as well as how well its developers have used patterns for solving their problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaroncollegeman.com/2009/02/gmail-filters-not-from/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
