<?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>Michael Barrett &#187; Development</title>
	<atom:link href="http://abouthalf.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://abouthalf.com</link>
	<description>@ Abouthalf.com</description>
	<lastBuildDate>Mon, 21 Jun 2010 02:55:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Congratulations</title>
		<link>http://abouthalf.com/2010/04/26/congratulations/</link>
		<comments>http://abouthalf.com/2010/04/26/congratulations/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 15:17:17 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=296</guid>
		<description><![CDATA[You shouldn&#8217;t have. I&#8217;m putting the finishing touches on a new WordPress theme. It&#8217;s still a little rough in places, comments need formatting, lists need sweetening, various twiddles need to be twaddled. But it&#8217;s mostly there, so why not take it for a test run? This theme is fully &#8216;widgetized&#8217; (to use the WordPress nomenclature) [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_297" class="wp-caption aligncenter frontispiece top-left" style="width: 475px"><a href="/wp-content/uploads/2010/04/marilynblows56.jpg"><img src="/wp-content/uploads/2010/04/marilynblows56.jpg" alt="Marilyn makes a wish" title="U1315234INP" width="475" height="517" class="size-full wp-image-297" /></a><p class="wp-caption-text">A new website?</p></div>
<p><em>You shouldn&#8217;t have.</em></p>
<p>I&#8217;m putting the finishing touches on a new WordPress theme. It&#8217;s still a little rough in places, comments need formatting, lists need sweetening, various twiddles need to be twaddled. But it&#8217;s mostly there, so why not take it for a test run?</p>
<p>This theme is fully &#8216;widgetized&#8217; (to use the WordPress nomenclature) which means it&#8217;s a lot easier to customize. I&#8217;m also working on a few fun little tricks like shortcodes (like for the image above) to allow for a little more aesthetic control of the published web content (while not borking the internal tools)</p>
<p>I have a couple of goals with this design: Use nice typography and keep it minimal. I realize the primary way people interact with a website nowadays is to follow a link from somewhere to the specific article. That link might be in an RSS feed reader, a search result, a twitter posting, or whatever. Very few people are going to websites directly to browse for content. </p>
<p>This has two implications: Reading is your user&#8217;s first priority. Searching is probably second, and actual clicking around on the site is a distant third (maybe fourth if you have some funny pictures of cats).</p>
<p>With this in mind I decided to keep the navigation minimal, and present the content front and center. Archives are off on their own page now (it&#8217;s widgetized, I could bring them back whenever), ancillary links are down at the bottom for when a reader gets done reading.</p>
<h3>Technical Notes</h3>
<p>Right now this theme should work in modern browsers including Internet Explorer 7 and 8. Internet Explorer 6 is probably making a mess of this site. I&#8217;m not sure if I care or not.</p>
<p>You may have noticed that this type ain&#8217;t Arial. I&#8217;m using new-ish font embedding techniques which should be rendering everything in a lovely Bodoni-esque typeface for you, unless you&#8217;re using an ancient version of Safari or Firefox. I am using <a href="http://www.fontsquirrel.com/">Font Squirrel</a> to create font kits. They host many open source or non-licensed fonts and provide a tool to roll your own font kits. </p>
<p>The rest of the theme is straight-forward HTML and CSS with a minor bit of tweaking to some default WordPress functions.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2010/04/26/congratulations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up PHP in Mac OS X 10.6 Snow Leopard</title>
		<link>http://abouthalf.com/2009/08/29/php-in-snow-leopard/</link>
		<comments>http://abouthalf.com/2009/08/29/php-in-snow-leopard/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 22:07:52 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=243</guid>
		<description><![CDATA[I updated my Mac with OS X 10.6 last night and the process went very smoothly without any problems. Apple does a good job with OS upgrades and installs, and they almost always go very smoothly. Most users can just pop in the disk, click the button, restart and go. In my case, I use [...]]]></description>
			<content:encoded><![CDATA[<p>I updated my Mac with OS X 10.6 last night and the process went very smoothly without any problems. Apple does a good job with OS upgrades and installs, and they almost always go very smoothly. Most users can just pop in the disk, click the button, restart and go.</p>
<p>In my case, I use my Mac for web development in PHP so I had a couple of extra tasks to perform.</p>
<p>I prefer to use the internal Apache 2 web server provided by Apple &#8211; mostly because it can be enabled and disabled with a click on a System Preference panel and the built in system log browser (Console.app) reports errors in Apache and PHP. Handy.</p>
<p>In the past I used pre-built and packaged PHP module from <a href="http://www.entropy.ch/software/macosx/php/">Mark Liyanage</a> &#8211; his package is the defacto standard for PHP development on a Mac, it&#8217;s linked from the <a href="http://www.php.net/downloads.php">PHP.net</a> site directly. Mark&#8217;s packages always work very well and have anything and everything you could want in a PHP binary. His packages are intended to work with the built in apache web server.</p>
<p>But Mark is only one man, and he can&#8217;t be expected to crank out a PHP package the same day a new operating system is released. Man&#8217;s got to eat.</p>
<p>Apple has bundled PHP (along with Ruby, Java, Python, and other developer tools) with Mac OS X from the beginning. However Apple&#8217;s versions of PHP are not always the most current, or may be missing features. Fore example, in OS X 10.5 Apple didn&#8217;t include PDO drivers for MySQL &#8211; which is a weird thing to leave out &#8211; but there you go. Thus most developers either compile their own versions of PHP (and ruby, and python, etc) or rely on a prepackaged binary.</p>
<p>However this time around, Apple&#8217;s included version of PHP is up to date and full featured (enough to be useful).</p>
<p>PHP 5.3 is included in Mac OS X 10.6 by default and this time they didn&#8217;t forget the PDO drivers for MySQL. Whee! Here is the configure command from the built in PHP on my system:</p>
<pre>'/var/tmp/apache_mod_php/apache_mod_php-53~1/php/configure'
'--prefix=/usr'
'--mandir=/usr/share/man'
'--infodir=/usr/share/info'
'--disable-dependency-tracking'
'--sysconfdir=/private/etc'
'--with-apxs2=/usr/sbin/apxs'
'--enable-cli'
'--with-config-file-path=/etc'
'--with-libxml-dir=/usr'
'--with-openssl=/usr'
'--with-kerberos=/usr'
'--with-zlib=/usr'
'--enable-bcmath'
'--with-bz2=/usr'
'--enable-calendar'
'--with-curl=/usr'
'--enable-exif'
'--enable-ftp'
'--with-gd'
'--with-jpeg-dir=/BinaryCache/apache_mod_php/apache_mod_php-53~1/Root/usr/local'
'--with-png-dir=/BinaryCache/apache_mod_php/apache_mod_php-53~1/Root/usr/local'
'--enable-gd-native-ttf'
'--with-ldap=/usr'
'--with-ldap-sasl=/usr'
'--enable-mbstring'
'--enable-mbregex'
'--with-mysql=mysqlnd'
'--with-mysqli=mysqlnd'
'--with-pdo-mysql=mysqlnd'
'--with-mysql-sock=/var/mysql/mysql.sock'
'--with-iodbc=/usr'
'--enable-shmop'
'--with-snmp=/usr'
'--enable-soap'
'--enable-sockets'
'--enable-sysvmsg'
'--enable-sysvsem'
'--enable-sysvshm'
'--with-xmlrpc'
'--with-iconv-dir=/usr'
'--with-xsl=/usr'
'--with-pcre-regex=/usr'</pre>
<p>Look at all those goodies. This has everything I need for my current development needs, so I didn&#8217;t bother with building my own PHP.</p>
<p>Before I began the upgrade process I made a copy of my apache configuration files. By default, apache on OS X creates a configuration file for each user account on the computer. These configuration files can be found in /etc/apache2/users/ and are named with your short user name, followed by &#8220;.conf&#8221; e.g. &#8220;username.conf&#8221;</p>
<p>I keep all of my apache development configurations in my user configuration file, so I just made a copy of that file and stashed it on my desktop.</p>
<p>While I&#8217;m comfortable mucking about in the command line, I&#8217;m a visual person and I prefer to see what I&#8217;m doing. Mac OS X typically hides the unix system files in the Finder &#8211; this prevents horrible accidents &#8211; but you can still use the Finder to dig around in the hidden file system.</p>
<p>In the Finder (i.e. click the desktop) select the &#8220;Go&#8221; menu at the top of the screen, look for the &#8220;Go to folder…&#8221; option.</p>
<p><img class="alignnone size-full wp-image-246" title="go-to-folder" src="/wp-content/uploads/2009/08/go-to-folder.png" alt="go-to-folder" width="335" height="360" /></p>
<p>This will bring up the following screen, where you can type the file path you want. You can even tab-complete path names.</p>
<p><img class="alignnone size-full wp-image-248" title="Go" src="/wp-content/uploads/2009/08/go-screen.png" alt="Go" width="509" height="229" /></p>
<p>Now you can browse all those sneaky hidden files, right-click them and edit them in TextMate</p>
<p><img class="alignnone size-full wp-image-249" title="Apache2 folder" src="/wp-content/uploads/2009/08/apache2_folder.png" alt="Apache2 folder" width="625" height="454" /></p>
<p>From here I could just drag the httpd.conf file to my desktop, and then dig into the users directory find my configuration file, and drag that to the desktop.</p>
<p>Next I made a back up of my MySQL databases by opening Terminal and typing:</p>
<p>
<pre><code>mysqldump -u root -p<em>password</em> --all-databases &gt; mysql_backup.sql</code></pre>
</p>
<p>Naturally you should use your own MySQL root password and not &#8220;password&#8221;. Naturally. This backup includes user tables as well as your databases, allowing you to reimport the whole kielbasa.</p>
<p>I ran a manual TimeMachine backup one more time to make sure I got everything backed up and then I ran the OS X 10.6 installer. Point. Click. Wait. Restart. Restart. Done. Easy.</p>
<p>After the update was done, I downloaded a new 64 bit intel installer for MySQL 5.0 here: http://dev.mysql.com/downloads/mysql/5.0.html#macosx-dmg &#8211; the site indicates OS X 10.5 but it works fine in 10.6</p>
<p>I reinstalled MySQL, the StartupItem, and the System Preference panel. From the command line I ran the following to reimport all of my data and users:</p>
<p>
<pre><code>mysql --user=root --password=<em>password</em> &lt; mysql_backup.sql</code></pre>
</p>
<p>The 10.6 installer honored my existing apache configuration files, so I didn&#8217;t actually have to replace those. But if you have never enabled PHP, simply go to /etc/apache2/ and edit httpd.conf in TextMate (TextMate will ask for your administrator password to save the file). Look for the line which reads:</p>
<p>
<pre><code>#LoadModule php5_module        libexec/apache2/libphp5.so</code></pre>
</p>
<p>Remove the pound sign (#) and save the file.</p>
<p>The default PHP installation on Mac OS X does not ship with a php.ini file. You&#8217;ll need to create one in order to configure PHP to find MySQL.</p>
<p>Go to /etc using the &#8220;Go&#8221; menu as indicated above. You should see a file entitled php.ini.default. Open this file in TextMate and save as &#8220;php.ini&#8221;</p>
<p>Set the server time zone by searching for &#8220;date.timezone&#8221; and setting the appropriate time zone ID from the lists here: <a href="http://us2.php.net/manual/en/timezones.php">http://us2.php.net/manual/en/timezones.php</a></p>
<p>I&#8217;m on the west coast, so I use <code>date.timezone = America/Los_Angeles</code></p>
<p>Note that there are no quotes around the time zone ID.</p>
<p>Next, you&#8217;ll need to point PHP to the mysql.sock file. The default values are incorrect. Search for &#8220;mysql.sock&#8221; and change each configuration to point to /tmp/mysql.sock &#8211; you should find three instances to change.</p>
<p>
<pre>pdo_mysql.default_socket=/tmp/mysql.sock</pre>
<pre>mysql.default_socket = /tmp/mysql.sock</pre>
<pre>mysqli.default_socket = /tmp/mysql.sock</pre>
</p>
<p>(In previous versions, Mac OS X kept the mysql.sock file at /var/mysql/mysql.sock &#8211; the new location is more standard)</p>
<p>If you are a seasoned PHP developer you may wish to make other configuration changes at this time. If not, leave the rest alone.</p>
<p>Save and close the file.</p>
<p>All that is left to do now is to open System Preferences, launch the MySQL system preference and start the server. Show All, select &#8220;Sharing&#8221; and check the box next to &#8220;Web Sharing&#8221; from the list of options.</p>
<p>To verify everything works &#8211; create a text file in your Sites directory called php_info.php and include the following:</p>
<p><code>&lt;?php phpinfo() ?&gt;</code></p>
<p>Load this file up in your browser at http://localhost/~username/php_info.php (replacing &#8216;username&#8217; with your user name) and you should see a nicely formatted list of all your PHP configurations.</p>
<p>Enjoy.</p>
<p>UPDATE: Rob Allen has some instructions up which include configuring Xdebug &#8211; very handy: <a href="http://akrabat.com/2009/10/05/setting-up-php-mysql-on-os-x-10-6-snow-leopard/">http://akrabat.com/2009/10/05/setting-up-php-mysql-on-os-x-10-6-snow-leopard/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2009/08/29/php-in-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t call it a bubble (the twitterconomy is a fickle mistress)</title>
		<link>http://abouthalf.com/2009/08/09/dont-call-it-a-bubble-the-twitterconomy-is-a-fickle-mistress/</link>
		<comments>http://abouthalf.com/2009/08/09/dont-call-it-a-bubble-the-twitterconomy-is-a-fickle-mistress/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 05:02:35 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=235</guid>
		<description><![CDATA[The URL shortening service tr.im is closing up shop, promising to maintain redirected URLs until December 2009. There is a lot of noise on Twitter and tr.im&#8217;s blog about the shut down. Apparently many users were using a feature of tr.im to generate ad hoc web site statistics &#8211; which was foolish even before tr.im [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/wp-content/uploads/2009/08/Picture-3.png"><img class="size-medium wp-image-236 alignnone" title="tr.im is closing up shop" src="/wp-content/uploads/2009/08/Picture-3-300x212.png" alt="tr.im is closing up shop" width="300" height="212" /></a></p>
<p>The <a href="http://tr.im/">URL shortening service tr.im</a> is closing up shop, promising to maintain redirected URLs until December 2009.</p>
<p>There is a lot of noise on Twitter and tr.im&#8217;s blog about the shut down. Apparently many users were using a feature of tr.im to generate ad hoc web site statistics &#8211; which was foolish even before tr.im shut off its service.</p>
<p>There are many little remora-like services that piggy back on Twitter&#8217;s success, Twitpic, Audioboo, and various URL shorteners.</p>
<p>Since I&#8217;m an old timer on the internets, my first reaction when one web site asks me for my username and password for another web site (under completely different ownership no less) is to get suspicious. I wonder how hard it would be to convince people to give up their bank website username and password, if you promised to print funny pictures of cats on their checks.</p>
<p>The folks at tr.im seem to be earnestly trying to prevent their domain name from falling into the hands of spammers, which I applaud. But it&#8217;s only a matter of time before one of the other services fails and sells out, and we get a web full of link rot <em>and </em>spam.</p>
<p>Twitter&#8217;s absurd 140 character limit is based on a primitive SMS limitation that is no longer <a href="http://en.wikipedia.org/wiki/Concatenated_SMS">relevant</a>. It&#8217;s this arbitrary limit which creates the need for URL shortening services in the first place, which Twitter strangely doesn&#8217;t provide internally (Twitter apparently hooks into bit.ly for URL shortening, but who knows how long that will last.)</p>
<p>If Twitter provided this service itself it would accomplish two things:</p>
<ul>
<li>Less link rot (if twitter dries up and blows away, so do the broken links)</li>
<li>Twitter could check for spam or malware laden links as a service to their users</li>
</ul>
<p>While I think shorter URLs are generally nicer to use (assuming they are somewhat intelligible when you read them) I think URL shortening services are just a tragedy waiting to happen.</p>
<p>A poorly authored (or a deliberately shady) URL shortening service can be used to obscure links to phishing sites, sites which try to install malware, or create links which actually contain malicious scripts themselves.</p>
<p>Since I&#8217;m not an active Twitter user, the only &#8216;follow&#8217; requests I receive are from spammy, porny, fake twitter users with only one &#8216;tweet&#8217; &#8211; the tweet containing, of course, some shortened URL from some service I&#8217;ve never heard of. (it&#8217;s interesting that most of my actual activity on the Twitter site itself is to block these spambots from following my account).</p>
<p>The giant gaping security holes in URL shortening services notwithstanding, I am a little surprised by the number of services who&#8217;s only business model seems to be &#8220;fill in a missing feature for Twitter and worry about making money later&#8221;.</p>
<p>A simple change at Twitter, say allowing Tweets to be 255 characters long, would basically shut down a number of web sites before they ever make any money.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2009/08/09/dont-call-it-a-bubble-the-twitterconomy-is-a-fickle-mistress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backblaze Review</title>
		<link>http://abouthalf.com/2009/08/08/backblaze-review/</link>
		<comments>http://abouthalf.com/2009/08/08/backblaze-review/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:44:20 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=225</guid>
		<description><![CDATA[I have constant backups made at home using Apple&#8217;s Time Machine (and it has in fact saved my butt more than once), I wanted to have the additional protection of having my files stored safely someplace other than my desk. I know some folks do off site backup the old fashioned way; by duplicating their [...]]]></description>
			<content:encoded><![CDATA[<p>I have constant backups made at home using Apple&#8217;s Time Machine (and it has in fact saved my butt more than once), I wanted to have the additional protection of having my files stored safely someplace other than my desk.</p>
<p>I know some folks do off site backup the old fashioned way; by duplicating their existing backup drive and storing it at a friend&#8217;s house. (In this scenario, the friend usually trusts you to store a copy of his backup too.)</p>
<p>The theory behind this approach is that the drive stored at your friend&#8217;s house should be relatively safe if your house burns down or gets broken into. And hey it&#8217;s all &#8220;free&#8221;.</p>
<p>However. I would never:</p>
<ul>
<li>Trust a friend with my personal files (my friend may be trustworthy&#8230;but what about his friends? or his wife? or his kids?)</li>
<li>Burden my friend with that responsibility</li>
<li>Take on that responsibility myself (do I look stupid to you?)</li>
</ul>
<p>That whole approach, while &#8220;free&#8221; seems like a good way to get your files stolen or damaged, get your heart broken, or just ruin a friendship. Besides, how often can you really expect you and your friend to swap drives? What if you miss a week or three ? What if one of you decides to move? Short version: This is a stupid idea.</p>
<p>I also looked into using Amazon S3 (and companion products). S3 is a clever product and is a bargain for any company with vast storage needs. For the home consumer though, the price is prohibitive, and it&#8217;s a little clunky. I do like the idea of a web-based back up system that I can use from anywhere.</p>
<p>So, I recently signed up to use <a href="https://www.backblaze.com/">Backblaze</a> for my offsite file backup provider. Blackblaze works wonderfully. It has the following killer features:</p>
<ul>
<li>Native Mac client</li>
<li>Cheap</li>
<li>Secure</li>
<li>Well thought out and easy to use</li>
</ul>
<p>Backblaze, at the time of this writing, charges $5 per month, per computer, for unlimited backup over the internet. Purchasing 1 year at a time costs a little less at $50. It would take me 2 to 3 years of service before I covered the cost of a new external hard drive &#8211; and external hard drives don&#8217;t come with off-site data centers, encryption, or web based file retrieval.</p>
<p><img class="push-0" title="Backblaze Menu Item Control" src="/wp-content/uploads/2009/08/Picture-1.png" alt="Backblaze Menu Item Control" width="93" height="78" />The software installs a control panel (Mac or Windows) and a little menu bar or system tray icon which lets you quickly see status or bring up the preferences.</p>
<p>The control panel itself is very simple, with a big fat &#8220;backup now&#8221; button and a simple status report.</p>
<p><a href="/wp-content/uploads/2009/08/bbcontrolpanel.png"><img title="Backblaze Mac OS X control panel" src="/wp-content/uploads/2009/08/bbcontrolpanel-300x214.png" alt="Backblaze Mac OS X control panel" width="300" height="214" /></a></p>
<p>Clicking &#8220;Settings…&#8221; will allow you to throttle the upload speed, schedule backups, or customize which files are backed up.</p>
<p>Backblaze, by default, assumes you want to backup everything except some commonly not backed up files, like caches, virtual disk images, and so forth. You choose what items that you explicitly <em>do not</em> want to back up. I think this approach makes a lot more since, especially for non-technical users. In my case, I omitted my downloaded TV programs (because I throw those away after I watch them anyway), my secondary user account, and some other non critical files (folders full of aliases). It would be nice to have an &#8220;advanced&#8221; mode to specify rules for backing up certain types of files, or to finely tune the backup schedule &#8211; but it&#8217;s not necessary.</p>
<p>Blackblaze has a few limitations imposed upon what you can back up. Backblaze limits backed up files to 4GB in size, they will not back up drives mounted over a network, and versions of files are only kept for 30 days. These limitations are perfectly reasonable to me &#8211; but Backblaze goes to the trouble of explaining each of their limitations in their FAQ.</p>
<p>Once you install Backblaze you must make your initial back up. This can take a <em>long</em> time, depending upon your network speed.</p>
<p>Obviously a web based backup system is going to require a speedy internet connection. Most home broadband internet providers give you a pretty good download speed, but the upload speed can be poor. Backblaze includes a <a href="https://www.backblaze.com/speedtest/">bandwidth speed test</a> on their site to help you determine how long your first back up will take. Mine took about three weeks, one of those weeks I was traveling and had limited access to the internet &#8211; so I&#8217;d wager that two weeks over a home DSL connection should be enough for most people.</p>
<p>Once my initial back up completed I immediately tried out a file restore to see how the system works (if you&#8217;re running any kind of back up system, you should periodically test that you can recover your files from your backup).</p>
<p>I used the web-based tool to select some arbitrary files from my backup. Backblaze presents you with a pretty nice tree-view browser to select your files. You can choose entire directories, individual files, or mix and match. Once you make your selection, Backblaze tells you you&#8217;ll get an email once your ZIP file download is ready. Mine came in about 2 seconds.</p>
<p>Following the link in the email, I discovered that not only does Backblaze keep your files, it keeps a record of the files you&#8217;ve restored. The restores are listed by date, can be downloaded again, or deleted if you don&#8217;t need them.</p>
<p>The ZIP file I downloaded retained the original directory structure of my hard drive, even though I only selected individual files, that is the zip decompressed to a folder with the name of my hard drive, with a &#8220;Users&#8221; folder, with my home folder, with a &#8220;Documents&#8221; folder, etc, etc. This would allow you to pretty easily reconstruct a destroyed system, or at the very least know where to find your files in your backup.</p>
<p>Overall, I&#8217;m very happy with this service. I hope I never really need it.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2009/08/08/backblaze-review/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Snarky responses to the Principles Behind the Agile Manifesto</title>
		<link>http://abouthalf.com/2009/01/11/snarky-responses-to-the-principles-behind-the-agile-manifesto/</link>
		<comments>http://abouthalf.com/2009/01/11/snarky-responses-to-the-principles-behind-the-agile-manifesto/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 01:56:17 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=200</guid>
		<description><![CDATA[The original principles can be found here: http://agilemanifesto.org/principles.html (if you&#8217;re into handwavium and naked emperors) Our highest priority is to satisfy the customerthrough early and continuous deliveryof valuable software. Because there&#8217;s nothing customers like more than half baked software. Welcome changing requirements, even late in development. Agile processes harness change for the customer&#8217;s competitive advantage. [...]]]></description>
			<content:encoded><![CDATA[<p>The original principles can be found here: <a href="http://agilemanifesto.org/principles.html">http://agilemanifesto.org/principles.html</a></p>
<p>(if you&#8217;re into <a href="http://en.wikipedia.org/wiki/Unobtainium#Science_fiction">handwavium</a> and naked emperors)</p>
<dl>
<dt>Our highest priority is to satisfy the customerthrough early and continuous deliveryof valuable software.</dt>
<dd>Because there&#8217;s nothing customers like more than half baked software.</dd>
<dt>Welcome changing requirements, even late in development. Agile processes harness change for the customer&#8217;s competitive advantage.</dt>
<dd>Because scope creep allows for us to bill more.</dd>
<dt>Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.</dt>
<dd>We couldn&#8217;t think of 12 principles, so we cut the first one in half and used it again.</dd>
<dt>Business people and developers must work together daily throughout the project.</dt>
<dd>Not like those other methodologies where developers create software in a perfect vacuum. In Space.</dd>
<dt>Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.</dt>
<dd>If your project fails, you just weren&#8217;t motivated enough.</dd>
<dt>The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.</dt>
<dd>If we don&#8217;t write anything down, we can&#8217;t get sued.</dd>
<dt>Working software is the primary measure of progress.</dt>
<dd>Meeting goals, deadlines, and budgets don&#8217;t count</dd>
<dt>Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.</dt>
<dd>Sustainable, constant development means we never stop billing.</dd>
<dt>Continuous attention to technical excellence and good design enhances agility.</dt>
<dd>We maximize our ROI by redeploying developer cycles in a proactive heads-down manner using Web 2.0.</dd>
<dt>Simplicity&#8211;the art of maximizing the amount of work not done&#8211;is essential.</dt>
<dd>This is the sound of one hand coding.</dd>
<dt>The best architectures, requirements, and designs emerge from self-organizing teams.</dt>
<dd>Because bullies, loudmouths, and jerks should run every project.</dd>
<dt>At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.</dt>
<dd>But don&#8217;t call it a performance review.</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2009/01/11/snarky-responses-to-the-principles-behind-the-agile-manifesto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lexical Closures are Handy</title>
		<link>http://abouthalf.com/2008/07/20/lexical-closures-are-handy/</link>
		<comments>http://abouthalf.com/2008/07/20/lexical-closures-are-handy/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 00:13:30 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=155</guid>
		<description><![CDATA[I wrote previously that I would write about a handy trick in JavaScript known as a &#8220;lexical closure&#8221;. This article has a great definition of a lexical closure: http://www.brockman.se/writing/method-references.html.utf8. I quote… Essentially, a closure, or lexical closure, is a function f coupled with a snapshot of its lexical environment (i.e., the non-local variable bindings used [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote <a href="/2008/07/18/javascript_scope_blues/">previously</a> that I would write about a handy trick in JavaScript known as a &#8220;lexical closure&#8221;.</p>
<p>This article has a great definition of a lexical closure: <a href="http://www.brockman.se/writing/method-references.html.utf8">http://www.brockman.se/writing/method-references.html.utf8</a>.</p>
<p>I quote…</p>
<blockquote>
<p>Essentially, a closure, or lexical closure, is a function f coupled with a snapshot of its lexical environment (i.e., the non-local variable bindings used in its body).</p>
<p>Hence, closing over some variable v means creating a closure that refers to v.</p>
<p>Strictly, the term “closure” can be used to describe any function that refers to one or more variables in an outer lexical scope. This is a rather broad definition that includes, for example, all functions that refer to global variables (such as document, alert, String, and so on).</p>
</blockquote>
<p>This can be very handy if you want, say, an event handling method to interact with both the HTML element the handler is attached to, and the parent object to which the method belongs. Huh? Exactly.</p>
<p>Let&#8217;s say you want to write a JavaScript object which encapsulates all of your form validation and preprocessing logic. Let&#8217;s say you want this object definition to include event handlers which validate form elements. After validation, you want the form elements to be visually updated to indicate if the value is correctly entered or not, and update the JS Object with any validation error messages.</p>
<p>First let&#8217;s write up some simple event handling utilities.</p>
<div><code>
<pre>// creates a function which
// 		executes an event handling method
// 		in the scope of a given object
function getBoundEventHandler(obj,method)
{
	return function(e)
	{
		e = e || window.event;
		method.call(obj,e);
	}
}</pre>
<p></code></div>
<div><code>
<pre>// cross-browser event-adder-on
function observeEvent(strEvent,obj,handle)
{
	if (window.addEventListener)
	{
		// W3C
		obj.addEventListener(strEvent,handle,false);
	}
	else
	{
		// Dirty, dirty MS Internet Explorer
		obj.attachEvent("on"+strEvent,handle);
	}
}</pre>
<p></code></div>
<p>Now let&#8217;s define a simple form handling object, with a simple means to report errors, and validate an alpha-numeric field.</p>
<p>First the constructor function:</p>
<div><code>
<pre>function Formbois(strFormId)
{
	var that = this; // Hot Lexical Closure Action!!
	var this.errors = new Array();
	var this.fieldKeyHandler = function(e)
	{
		// with the handler function bound to the target element,
		//   "this" refers to the form element
		// "that" refers to the Formbois instance
		if (!that.validateAlphaNum(this.value))
		{
			// add an error to the errors array
			that.errors.push("Please enter an alpha-numeric value");
			// mark the form element having an error
			this.className += " error";
		}
		else
		{
			this.className += " valid";
		}

	}
}</pre>
<p></code></div>
<p>Based upon what I mentioned in my previous post, the private variable &#8220;that&#8221; is in the same lexical scope as the function &#8220;fieldKeyHandler&#8221;. That means when I assign that method to a form element, the variable &#8220;that&#8221; will refer to the instance of the object &#8220;Formbois&#8221; allowing me to access the public method &#8220;validateAlphaNum&#8221; and the &#8220;errors&#8221; array. Neat.</p>
<p>Let&#8217;s define the validator and the error reporter for a complete example:</p>
<div><code>
<pre>
Formbois.prototype.validateAlphaNum = function(value)
{
	return value.match(/[a-z][A-z][0-9]/))

}

Formbois.prototype.alertErrors = function()
{
	alert(this.errors.join("\n"));
}</pre>
<p></code></div>
<p>Neither of these methods have access to the private variable &#8220;that&#8221;, but that&#8217;s OK because they don&#8217;t need it. The method &#8220;validateAlphaNum&#8221; could even be a static function assigned like so:<br />
<code>Formbois.validateAlphaNum = function(value) { /*[.code goes here.]*/ }</code></p>
<p>To put it all together, we instantiate the &#8220;Formbois&#8221; object and assign our event handler.</p>
<div><code>
<pre>// create form object
var f = new Formbois("happyFunForm");
// get form element
var elm = document.getElementById("someTextFieldId");
// assign event handler to "onkeyup" event
observeEvent(
		"keyup",
		elm,
		getBoundEventHandler(elm,f.fieldKeyHandler)
	);</pre>
<p></code></div>
<p>Obviously this is a very simple example, but hopefully it will inspire someone to write some JavaScript which doesn&#8217;t suck.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2008/07/20/lexical-closures-are-handy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Scope Blues</title>
		<link>http://abouthalf.com/2008/07/18/javascript_scope_blues/</link>
		<comments>http://abouthalf.com/2008/07/18/javascript_scope_blues/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 15:41:54 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=154</guid>
		<description><![CDATA[I&#8217;ve been working out some methods of making uniquely namespaced JavaScript objects. I&#8217;m trying to handle a situation where there could be multiple instances of the same object or functions on the same page with the same name. The idea is to prevent one function, variable, or object accidentally writing over another because they have [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve been working out some methods of making uniquely namespaced JavaScript objects.
</p>
<p>
I&#8217;m trying to handle a situation where there could be multiple instances of the same object or functions on the same page with the same name. The idea is to prevent one function, variable, or object accidentally writing over another because they have the same name.
</p>
<p>
I settled on a <a href="http://en.wikipedia.org/wiki/Factory_Pattern">factory pattern</a> which accepts a namespace as a parameter, followed by an array or object of parameters.
</p>
<p>
I start with a factory function which does some simple checking for a namespace, and then calls a constructor function, assigning the resulting object to a global property of the window object.
</p>
<p>
This code assumes that &#8220;namespace&#8221; is a unique value.
</p>
<div><code>
<pre>function myObjFactory(namespace,objParameters)
{
	if (!namespace)
	{
		throw new Error("Null Parameter 'namespace'");
	}
	window[namespace] = new MyObj(objParameters);
}</pre>
<p></code></div>
<p>
So in JavaScript the way to create a custom object is to define a function, and call it with the &#8220;new&#8221; keyword, as above. Your function can accept any parameters you wish. These parameters can be used to set default values in your object, or operated on by internal functions.
</p>
<p>
In JavaScript everything is an object, including functions. Functions have a public property &#8220;caller&#8221; which holds a reference to the function or object which called the function. So in my example below, if I try to call my constructor function from anywhere but the function &#8220;myObjFactory&#8221; it will throw an error. This little trick makes it impossible to instantiate MyObj without myObjFactory, ensuring my design pattern doesn&#8217;t unravel.
</p>
<div><code>
<pre>function MyObj(objParameters)
{
	if (MyObj.caller != myObjFactory)
	{
		throw new Error("No public constructor for MyObj.
			 Use myObjFactory");
	}
	var shy = "private value";
	this.params = objParameters;
	this.arbitraryHandler = function(e) { return e;}
	this.publicFunction = function() { alert(shy);}
}</pre>
<p></code></div>
<p>
Notice that some members of this function are prefixed by &#8220;this&#8221;. Those values become public properties of the object once it&#8217;s instantiate.
</p>
<p>
The variable &#8220;shy&#8221; is scoped within MyObj, so it functions as a private variable. The functions &#8220;arbitraryHandler&#8221; and &#8220;publicFunction&#8221; can both access &#8220;shy&#8221; but shy cannot be accessed from outside the function, e.g. the following would throw an error:
</p>
<div><code>
<pre>//instance of MyObj from the window object;
var moe = window[namespace]
alert(moe.shy); // FAIL - private variable.</pre>
<p></code></div>
<p>
Super. Now I have public and private members in JavaScript. And they said it couldn&#8217;t be done!
</p>
<p>
The OO JavaScript convention is to write a lean constructor object, and then append public methods or properties to the function&#8217;s <em>prototype</em> property. Like so:
</p>
<p><code>
<pre>MyObj.prototype.newProperty = "shiny";
MyObj.prototype.newMethod = function(parm) {alert(parm);}</pre>
<p></code></p>
<p>
Anything you add to an object&#8217;s prototype is available to all instances of that object.
</p>
<p>
But here&#8217;s where I got off the rails. Remember my private member &#8220;shy&#8221;? The variable &#8220;shy&#8221; isn&#8217;t a private member in the same way that a member is private in a classical language like Java or C#.
</p>
<p>
It only acts private because it available to the local scope of the constructor function. So when I tried something like this, it fails:
</p>
<p><code>
<pre>MyObj.prototype.getShy = function() {alert(shy);} //FAIL</pre>
<p></code></p>
<p>
Doh. What went wrong?
</p>
<p>
All members of objects in JavaScript are public, any variables tucked away within a function are local to that function. When I added a method to the objects prototype, the local scope of the function is not available (and to be double plus specific, I added a method to the object&#8217;s <em>prototype</em> which in reality is the object which my object is based upon or inherits from; Object in this case; so I was really adding a public method to an entirely different object)
</p>
<p>
To summarize, if you&#8217;re writing OO JavaScript, and you want to store some private values accessible by public methods &#8211; place both your private values <em>and</em> your public methods in the same scope, i.e. the constructor function.
</p>
<p>
This also opens up a neat trick called a &#8216;lexical closure&#8217; which can be very handy when writing complex event handlers or callback functions &#8212; which I&#8217;ll write about next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2008/07/18/javascript_scope_blues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weekend Round-up</title>
		<link>http://abouthalf.com/2008/07/06/weekend-round-up/</link>
		<comments>http://abouthalf.com/2008/07/06/weekend-round-up/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 18:47:49 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Play]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://abouthalf.com/?p=150</guid>
		<description><![CDATA[Just when I thought &#8220;A List Apart&#8221; had become a useless dried up husk of RoR wankers, they turn around and publish this gem of an article: Getting Out of Binding Situations in JavaScript I&#8217;ve read various descriptions of &#8216;binding&#8217; in JavaScript before, but this is probably the most clear explanation I&#8217;ve seen. As a [...]]]></description>
			<content:encoded><![CDATA[<p>Just when I thought &#8220;A List Apart&#8221; had become a useless dried up husk of RoR wankers, they turn around and publish this gem of an article: <a href="http://www.alistapart.com/articles/getoutbindingsituations">Getting Out of Binding Situations in JavaScript</a></p>
<p>I&#8217;ve read various descriptions of &#8216;binding&#8217; in JavaScript before, but this is probably the most clear explanation I&#8217;ve seen. As a bonus, someone in the comments linked to this fine, incredibly thorough, advanced discussion of binding: <a href="http://www.brockman.se/writing/method-references.html.utf8">Object-Oriented Event Listening through Partial Application in JavaScript</a>.</p>
<p>You can tell by the title that this article is not for the faint of heart. (hint: start with the ALA article)</p>
<hr />
<p><a href="http://37signals.blogs.com/products/2008/07/basecamp-phasin.html">37 Signlas</a> is dropping support for Internet Explorer 6. It must be nice to fire your customers from time to time.</p>
<hr />
<p><img src="http://abouthalf.com/wp-content/uploads/2008/07/me-and-she-at-the-beach.jpg" alt="Me and She at the beach" title="me-and-she-at-the-beach" width="350" height="262" class="alignnone size-full wp-image-151" /></p>
<p>The missus and spent a lovely Saturday at Cannon Beach, OR. We had it all. Blankets, towels, trashy magazines to read, hot dogs, marshmallows. Except Ketchup. And Sunscreen. Ouch.</p>
<hr />
<p>The first anniversary is fast approaching. We&#8217;re taking the train up to Seattle to stay in a kitschy old <a href="http://www.moorehotel.com/">hotel</a> and eat at a swanky tucked away <a href="http://www.thepinkdoor.net/">restaurant</a> rumored to have a trapeze act and a burlesque show. Ooh La La.</p>
<hr />
<p><img src="http://abouthalf.com/wp-content/uploads/2008/07/independence-day-with-a-dutchman.jpg" alt="Independence Day with a Dutchman" title="independence-day-with-a-dutchman" width="350" height="262" class="alignnone size-full wp-image-152" /></p>
<p>I spent part of the Fourth in a friend&#8217;s back yard grilling various things and eating fancy cheese. We had a Dutchman (pictured) and a Brit in attendance (along with various liberal Portlandy types). Viva La Independencia.</p>
<hr />
<p>I&#8217;ve caved into the pressure and signed up on the <a href="http://www.facebook.com/profile.php?id=1327749623">Facebook</a>. And while I&#8217;m at it, I&#8217;m on the <a href="http://www.linkedin.com/in/abouthalf">LinkedIn</a> too. Damn kids. And their internets.</p>
<p>I&#8217;ve been using the <a href="http://twitter.com/device55">Twitter</a> lately also. I&#8217;m not sure how I feel about it. Like any good RoR app: it&#8217;s horribly unreliable; it&#8217;s purpose is rather unclear; and all the cool kids are doing it. Twitter claims to be a &#8220;micro blogging&#8221; application, but people use it as an ad-hoc messaging system or bulletin board. It is useful for keeping up with prolific bloggers. The <a href="http://twitter.com/MarsPhoenix">Mars Phoenix program</a> has been posting updates as well, which is fairly neato. However, <em>I&#8217;m</em> not convinced it&#8217;s worth <em>my</em> time to post anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2008/07/06/weekend-round-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>These are headlines</title>
		<link>http://abouthalf.com/2008/01/16/these-are-headlines/</link>
		<comments>http://abouthalf.com/2008/01/16/these-are-headlines/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 03:46:11 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/2008/01/16/these-are-headlines/</guid>
		<description><![CDATA[Recent news followed by my pithy remarks. MacBook Air Announced Without Pony. Bloggers Demand Pony. The (ever) Daring Fireball and Paul Boutin at Slate are lamenting the fact that the newly announced Mac sub-notebook doesn&#8217;t have some manner of cellular EVDO type of use-anywhere-networking-just-like-the-iPhone support. A quote: Like me, Boutin was hoping for ubiquitous wireless [...]]]></description>
			<content:encoded><![CDATA[<p>Recent news followed by my pithy remarks.</p>
<h2><a href="http://www.apple.com/macbookair/">MacBook Air</a> Announced Without Pony. Bloggers Demand Pony.</h2>
<p><a href="http://daringfireball.net/linked/2008/january#wed-16-boutin">The (ever) Daring Fireball</a> and <a href="http://slate.com/id/2182227/">Paul Boutin at Slate</a> are lamenting the fact that the newly announced Mac sub-notebook doesn&#8217;t have some manner of cellular <a href="http://en.wikipedia.org/wiki/Evolution-Data_Optimized">EVDO</a> type of use-anywhere-networking-just-like-the-iPhone support. A quote:</p>
<blockquote><p>Like me, Boutin was hoping for ubiquitous wireless networking. The more I think about this, the more certain I am that itâ€™s just silly that my phone always has a network and (as of yesterday) knows where it is, but my Mac doesnâ€™t.</p></blockquote>
<p>While, yes, it may in fact be technically feasible to incorporate a cellular card into a skinny little laptop and offer the same clever network switch-a-roo technology that is in the iPhone, that doesn&#8217;t mean it&#8217;s a good or profitable idea.</p>
<p>To rebut this point: It&#8217;s a laptop, not a phone! Do you need your TV to geo-locate? How about your printer? Maybe your microwave?</p>
<p>To rebut in a slightly more classy fashion, Consider the two following use cases:</p>
<ol>
<li>You are in a new or unfamiliar location, perhaps walking or driving. Perhaps you&#8217;ve missed a turn out in the &#8216;burbs. You realize &#8220;oh foo, I don&#8217;t know where I am any more.&#8221; You need directions.</li>
<li>You suddenly realize you&#8217;re in a strange coffee shop, using your laptop, and realize &#8220;oh foo, I don&#8217;t know where I am&#8221;. You need directions.</li>
</ol>
<p>I&#8217;m going to wager that case 1 is the most common. I can remember at least a few times I&#8217;ve been in just that predicament. This is why the iPhone has a Google Maps application with a location feature.</p>
<p>If case number 2 is happening to you often enough to consider a laptop upgrade, perhaps you need to switch to decaf.</p>
<p>Paul Boutin, in his article, posits the scenario where he&#8217;s riding shotgun in a car, and wants to help the driver with directions, so he <em>wants to dig around in his bag and boot up his laptop instead of picking up a cellphone and calling for directions.</em> This strikes me as an edge case.</p>
<p>I think that is what Apple thinks too. Yeah, they could do it. But why?</p>
<p>There are hard-core super road warriors who need connectivity everywhere. But these guys are (a) a small market and (b) are purchasing &#8220;pro&#8221; versions of laptops and plugging in whatever wireless provider&#8217;s card they need.</p>
<p>There&#8217;s a laundry list of other reasons why this is a dumb idea for this particular computer:</p>
<ul>
<li>Who will the provider be, Sprint? ATT? Should Apple standardize on one provider, or provide generic hardware? If so, who supports what? Can Apple guarantee that fickle telecommunications companies won&#8217;t pull the plug on hardware support in a year?</li>
<li>What hardware standard do you support? Do you hope for 3G? Do you use Edge? Do you put a giant chunky card-slot on your sleek, whisper thin computer that only 1 out of a 100 owners will use?</li>
<li>See above, the target customer for this computer doesn&#8217;t want this.</li>
<li>Data connections over cellular networks suck, yes even 3G is only as good as a good dial-up connection.</li>
<li>The MacBook Air sports 5 hours of battery life. How&#8217;d you like to make that <em>3</em>?</li>
</ul>
<p>I see three big markets for the MacBook Air, in descending order:</p>
<ol>
<li>People with one beefy machine at home or in the office who want a second, small computer for traveling, giving presentations, or otherwise using on the go</li>
<li>Students. This laptop will fit in your <a href="http://www.trapperkeeper.com/">TrapperKeeper</a> along side all 18 of your chemistry books. (When I mentioned the Air to my wife she remarked &#8220;oh, what I wanted a year ago.&#8221;)</li>
<li>People who don&#8217;t need or want a beefy computer, and want something small and light that looks nice and isn&#8217;t complicated (Hi Paris!).</li>
</ol>
<h2>Hosting Provider Makes Point. Point Missed.</h2>
<p>It started here:<br />
<a href="http://blog.dreamhost.com/2008/01/07/how-ruby-on-rails-could-be-much-better/">http://blog.dreamhost.com/2008/01/07/how-ruby-on-rails-could-be-much-better/</a></p>
<p>And went here:<br />
<a href="http://www.al3x.net/2008/01/shared-hosting-is-ghetto.html">http://www.al3x.net/2008/01/shared-hosting-is-ghetto.html</a></p>
<p>Link number one &#8211; the author, a tech at Dreamhost (where I host my web sites), writes a constructive article detailing the difficulties they encountered in trying to support the Ruby On Rails framework. Also, he articulates his opinion that if the Rails community could standardize their hosting and deployment practices &#8211; or at least provide a set of best practices that can be easily repeated &#8211; and make it easy to deploy in shared hosting environments, it would really benefit Rails developers (to provide cheap hosting environments for learning and development) and help promote Rails as a technology.</p>
<p>These are true statements, with which I agree completely. (They are also born out by tales of woe I&#8217;ve heard myself from folks who tried to manage their own Rails environment, on their own servers.)</p>
<p>Link number two: Rails dude gets snippy and calls shared hosting a ghetto (in reference to an <a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html" title="Long, Technical, Ranty">article</a> by an ex-Rails developer) and misses the point entirely. This second article makes points about how Java and Python have stayed away from shared hosting (<a href="http://www.google.com/search?hl=en&#038;safe=off&#038;rls=en&#038;q=java+hosting&#038;btnG=Search">not</a> entirely <a href="http://www.google.com/search?rls=en&#038;q=shared+Python+hosting&#038;ie=UTF-8&#038;oe=UTF-8 ">true</a>). He then proceeds to discuss his preference for the &#8220;nightmare&#8221; of setting up his own server versus the nightmare setting up a shared server (pick your poison, I suppose). </p>
<p>He concludes by incorrectly identifying a popular hosted PHP application as a Rails app and trying to argue that shared hosting wouldn&#8217;t make him any money. Oh. Well then. Point made, I guess.</p>
<p>Dallas Kashuba at the Dreamhost blog is correct. Rails is very troublesome to host and deploy. This problem &#8211; regardless of whether the hosting is in the shared hosting ghetto or in your personal server farm &#8211; is still a problem and a deal-breaker for a lot of people. It certainly was for me. Getting all snippy doesn&#8217;t change that fact.</p>
<p>The Michael Barrett Professional Opinionâ„¢ is that Ruby on Rails is all sizzle and no steak. The development problems it solves are only solved if you&#8217;re starting with a fresh, clean, empty database; have no legacy systems or data to integrate to, and have lots of time to babysit a server. </p>
<p>Call me when RoR reaches version 3, 4, or 5. Maybe we&#8217;ll try again.</p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2008/01/16/these-are-headlines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking of layout updates</title>
		<link>http://abouthalf.com/2007/12/31/speaking-of-layout-updates/</link>
		<comments>http://abouthalf.com/2007/12/31/speaking-of-layout-updates/#comments</comments>
		<pubDate>Mon, 31 Dec 2007 10:26:52 +0000</pubDate>
		<dc:creator>MB</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://abouthalf.com/2007/12/31/speaking-of-layout-updates/</guid>
		<description><![CDATA[I&#8217;ve created my own WordPress Theme (coinciding nicely with the 2.3.2 upgrade). When I kissed RapidWeaver goodbye, and re-familiarized myself with WordPress, I didn&#8217;t want to spend time customizing a web site design&#8230;I just wanted to fix the problem of me not posting very often. I discovered the Ideal Website theme &#8211; which is pretty [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve created my own WordPress Theme (coinciding nicely with the <a href="http://wordpress.org/development/2007/12/wordpress-232/">2.3.2</a> upgrade).</p>
<p>When I kissed <a href="http://abouthalf.com/2007/09/09/software-updates/">RapidWeaver goodbye</a>, and re-familiarized myself with WordPress, I didn&#8217;t want to spend time customizing a web site design&#8230;I just wanted to fix the problem of me not posting very often. I discovered the <a href="http://www.informationarchitects.jp/the-ideal-website">Ideal Website</a> theme &#8211; which is pretty nice <em>looking</em> but the HTML which is ultimately generated is pretty much tag-soup (nee Crap). Also, oddly, the website advertising the theme boasts all this &#8220;openness&#8221;&#8230;but the license that ships with the theme is fairly restrictive&#8230;silly, dubiously legal, software boilerplate legalese which only sort of applies (How much can you really copyright an open source template API and standard HTML implementation if you&#8217;re just giving it away?). Needless to say, I don&#8217;t want to be encumbered by that noise. I might want to change the typeface or something. </p>
<p>So, with the holidays in full pause, I had time to rework things. I&#8217;m reusing a very old background image from one of this site&#8217;s previous incarnations along with my <em>classic</em> logo. I did steal one idea from the Ideal theme&#8230;the contact form at the bottom of the page. That&#8217;s a clever idea really. Why should that be a separate page? As I continue to tweak things, I may make that collapsible so it&#8217;s only visible when needed&#8230;but I like not sending a visitor off to another page to ask me something.</p>
<p>I&#8217;m taking advantage of the nifty <a href="http://code.google.com/p/blueprintcss/">Blueprint CSS framework</a> to simplify my layout needs. The framework is really quite nice, I&#8217;ve been using at work for quite a while now. It greatly simplifies your page layout work, and also makes it simple for me to do more &#8216;designed&#8217; blog posts by taking advantage of the framework&#8217;s existing CSS class names.</p>
<p>The layout is based on a simple vertical grid, with classical proportions: 8x5x3. The center column (5) appears as whitespace wherever more focus is desired (viewing a single post or page, for example). Type is set on an 18 pixel <a href="http://www.alistapart.com/articles/settingtypeontheweb/">baseline grid</a> which gives everything a nice rhythm and makes it easier to read.</p>
<p>As I continue to tweak this, I&#8217;d like to:</p>
<ul>
<li>Integrate some bolder color in an effective fashion</li>
<li>Gracefully hide or show elements on the page as they are needed via JavaScript</li>
<li>Add a comments policy and a contact policy (just in case)</li>
<li>Finally get some portfolio on line</li>
</ul>
<p><strong>The <a href="http://abouthalf.com/2007/12/29/flickr-phobia/">flickr</a> question</strong></p>
<p>Flickr sucks. I spent a few hours playing with itâ€¦It&#8217;s slow. The tools don&#8217;t work very well (e.g. odd, useless error messages with raw xml strings. <em>Great. Thanks.</em>). I decided that if I want to share photos with people I&#8217;ll use Google&#8217;s picassa, and otherwise I&#8217;ll just post any worthwhile pictures in the blog.</p>
<p><a href="http://picasaweb.google.com/device55/HoneymoonInMazatlanMexico">And here are some honeymoon pictures.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://abouthalf.com/2007/12/31/speaking-of-layout-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.170 seconds -->
