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

<channel>
	<title>Foo Hack</title>
	<atom:link href="http://foohack.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://foohack.com</link>
	<description>Isaac Schlueter on Web Development</description>
	<pubDate>Wed, 07 May 2008 06:20:49 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Steal My Bash Profile</title>
		<link>http://foohack.com/2008/05/steal-my-bash-profile/</link>
		<comments>http://foohack.com/2008/05/steal-my-bash-profile/#comments</comments>
		<pubDate>Wed, 07 May 2008 03:32:22 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Freebie]]></category>

		<category><![CDATA[Tools of the Trade]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=66</guid>
		<description><![CDATA[Feel free to skip the monologue and just get the goodies.

I am in love with the Bourne Again Shell.  Bash is a fantastic terminal environment, and a very interesting programming language in its own right.

I grew up using DOS.  Unix shells always seemed scary and foreign, for some reason.  I think a <small><a href="http://foohack.com/2008/05/steal-my-bash-profile/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p><small>Feel free to skip the monologue and just <a href="http://foohack.com/tests/bash_extras/" class="internal">get the goodies</a>.</small></p>
<p>I am in love with the <a href="http://www.gnu.org/software/bash/manual/bashref.html" rev="vote-for" class="external">Bourne Again Shell</a>.  Bash is a fantastic terminal environment, and a very interesting programming language in its own right.</p>
<p>I grew up using DOS.  Unix shells always seemed scary and foreign, for some reason.  I think a big part of the reason that I stayed on Windows for as long as I did was that I knew DOS, and could always resort to it in times of need.  As a support tech in college, I got very familiar with DOS.  It was comfortable and handy.</p>
<p>When I got into web programming, I had no choice but to learn at least the rudimentary basics of a unix-style environment.  At that time, I was as a support tech at a software company whose product uses VisualBasic ASP over IIS, and had started playing around in that environment.  However, I had no money, and web hosts that support ASP cost money.</p>
<p>By some stroke of luck or persistence, I managed to find a host that was free, <a href="http://beigetower.org" class="external">Beigetower</a>. <small>That link doesn&#8217;t work any more, of course.  I don&#8217;t know how long that server&#8217;s been down.  Cuong Nghiem&#8217;s still listed as the owner on whois, though.)</small>  On top of that, they provided shell access.  Not being able to resist the temptation to tinker with a real live web server, I learned enough Bash to poke around.  As I learned more PHP, I picked up more bits and pieces along the way.</p>
<p>When I started at Yahoo, it was sink or swim to some extent.  I was issued a FreeBSD dev box, and a windows desktop.  I did most of my development in my safe windows world, but there are *a lot* of things you have to do on your dev box as an engineer at Yahoo that simply can&#8217;t be done in any other way.  Bash was a regular part of my daily routine almost from the first day.</p>
<p>Eventually, I fell so head over heels in love with Bash that I had to say goodbye to Windows and get a Mac.</p>
<p>There are many good reasons to get a Mac instead of a PC. They&#8217;re easier and more intuitive in a lot of ways.  They certainly look a lot nicer on almost every level.  But I&#8217;d be lying if I said that having Bash right there all the time wasn&#8217;t the ultimate dealmaker.</p>
<p>One of the best things about Bash, in my opinion, is the fact that you can add shortcuts to your <code>.profile</code> (or <code>.bash_profile</code> or <code>.bashrc</code>, of course) that will be loaded every time you log in.  As soon as I learned this, I started adding stuff.</p>
<p>Eventually, I had my profile so tricked out that it was hideously painful to have to work on a machine that didn&#8217;t have my shortcuts.  Without my customized prompt, I&#8217;d get really confused about which directory I was currently in, and have to type <code>pwd</code> every three seconds just to not get lost.  The sequence would usually go like this:</p>
<p><code class="block">$ la<br />
-bash: la: command not found<br />
$ la<br />
-bash: la: command not found<br />
$ la<br />
-bash: la: command not found<br />
$ alias la="ls -laF"</code></p>
<p>Those first few entries of <code>la</code> were accompanied by plenty of growling and confusion, <em>every. single. time.</em></p>
<p>So, I got into the habit of using <code>scp</code> or <code>rsync</code> to send my bash profile to any machine that I&#8217;d have to work on.  However, some machines have <code>vi</code>, and some don&#8217;t.  I&#8217;d make a change on the profile on my mac, and forget to sync it to my dev box.  Machines that I didn&#8217;t log into often would be so far out of date that it was the &#8220;la&#8221; situation all over again.  What&#8217;s worse, I put some stuff in other shell script files that were called by the profile to do other things, so it was no longer straightforward to keep them in sync.  I&#8217;d send half the package, and then log in, and be inundated with errors all over the place.</p>
<p>When I switched from FreeBSD to a Red Hat Linux box, half my stuff didn&#8217;t work quite the same way.  Also, I moved Foo Hack to a great <a href="http://www.slicehost.com/" rev="vote-for" class="external">new host</a>, which is running Ubuntu.  On the Mac, I use <a href="http://macports.org" class="external">MacPorts</a>, and the Ubuntu slice uses <a href="http://www.debian.org/doc/manuals/apt-howto/" class="external">apt-get</a>, and the RHEL of course uses yinst, the Yahoo! package management tool that quite simply makes all others look like crap by comparison.  (Sadly, yinst is not open source.  There&#8217;s <a href="http://svn.marc.abramowitz.info/projects/hacks/yinst" class="external">this hack</a> to simulate yinst on top of apt, though.)  The Ubuntu and RHEL environments used vi as the default editor, but I&#8217;d changed that on the Mac to point to <code>mate</code>, the command-line interface to <a href="http://macromates.com" class="external">TextMate</a>.</p>
<p>To say the least, a simple sync wasn&#8217;t cutting it even a little.</p>
<p>I re-wrote all my bash profile goodies to fit in a single file.  Shell scripts were replaced with functions so that they could all live together.  The <code>edit</code> command was defined to use the first available editor from a list of alternatives.  Then, I put it in a file that was external from the main <code>.profile</code> or <code>.bashrc</code> file, so that it could be synced without overwriting anything that the OS placed in there by default.  The only thing to do on a new server was to add <code>. ~/.extra.bashrc</code> to the bottom of whatever profile script it was already using.</p>
<p>I had already added a command called <code>editprof</code> that would bring my profile up in an editor.  All that was needed then was a <code>pushprof</code> command that would rsync the .extra.bashrc file to a given host.</p>
<p>I&#8217;m releasing it under the <a href="http://sam.zoy.org/wtfpl/" class="external">WTFPL</a>.  There are actually a few files, since some stuff simply didn&#8217;t make any sense to have in certain environments.  The copy here on foohack.com is symlinked from my home directory, so it&#8217;ll stay pretty up to date.  Feel free to copy, learn, or, like the license says, just do <abbr title="what the fuck">wtf</abbr> you like with it.</p>
<p>A word of warning: like government regulation, this file increases in size but rarely gets revised.  Some stuff may be completely useless or pointless.  Some of it I hardly ever use any more.  Figuring out better solutions to these problems is left as an exercise for the reader.</p>
<p><a href="http://foohack.com/tests/bash_extras/" class="internal">Get my bash extras.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/05/steal-my-bash-profile/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Open in TextMate in Finder for Tiger</title>
		<link>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/</link>
		<comments>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 09:03:49 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Freebie]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=64</guid>
		<description><![CDATA[This post has a great little droplet that can be added to the Finder toolbar to open either the selected items or the current Finder folder in TextMate.

Sadly, it doesn&#8217;t work in Tiger, and I haven&#8217;t made the jump to Leopard yet.  If you&#8217;re a TextMate user who&#8217;s still on Tiger, and wants this <small><a href="http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p><a href="http://henrik.nyh.se/2007/10/open-in-textmate-from-leopard-finder" class="external">This post</a> has a great little droplet that can be added to the Finder toolbar to open either the selected items or the current Finder folder in TextMate.</p>
<p>Sadly, it doesn&#8217;t work in Tiger, and I haven&#8217;t made the jump to Leopard yet.  If you&#8217;re a TextMate user who&#8217;s still on Tiger, and wants this feature, I tweaked Henrik&#8217;s AppleScript to play nice with Tiger.</p>
<p><a href="http://foohack.com/blog/wp-content/uploads/2008/04/open-in-textmate-tiger.dmg" class="internal">Open in TextMate (for Tiger)</a></p>
<p>Enjoy!</p>
<p><ins datetime="2008-05-04T06:50:12+00:00"><strong>Update</strong>: Just fixed the script to work with folders and files that have spaces in the name.</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/04/open-in-textmate-in-finder-for-tiger/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OpenSocial, Meetings, and Success</title>
		<link>http://foohack.com/2008/04/opensocial-meetings-and-success/</link>
		<comments>http://foohack.com/2008/04/opensocial-meetings-and-success/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 19:20:41 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[20-20 Hindsight]]></category>

		<category><![CDATA[Status Update]]></category>

		<category><![CDATA[The Business]]></category>

		<guid isPermaLink="false">http://foohack.com/?p=63</guid>
		<description><![CDATA[It&#8217;s a very interesting time for me at Yahoo! right now.  I&#8217;d been keeping quiet about what&#8217;s going on for two big reasons.  First, I&#8217;ve been too busy working to write about it.  Second, it&#8217;s secret.

Well, as of 2008 March 25, it was a secret.  This press release broke the news <small><a href="http://foohack.com/2008/04/opensocial-meetings-and-success/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a very interesting time for me at Yahoo! right now.  I&#8217;d been keeping quiet about what&#8217;s going on for two big reasons.  First, I&#8217;ve been too busy working to write about it.  Second, it&#8217;s secret.</p>
<p>Well, as of 2008 March 25, it <em>was</em> a secret.  <a href="http://yhoo.client.shareholder.com/press/releasedetail.cfm?ReleaseID=301421" class="external">This press release</a> broke the news a few days ago, so I doubt I&#8217;m giving anything away to say that Yahoo! is busy working on implementing a framework for <a href="http://code.google.com/apis/opensocial/" class="external">OpenSocial</a> applications that tie into various sorts of Yahoo! data.</p>
<p><a href="http://buzz.yahoo.com" class="external">Buzz</a> was a very fun project to work on.  After games&#8217; mountain of legacy and the brand universe fiascos, it was really great to be able to have a hand in developing a site from scratch and also have enough space and resources to really create quality.  (It has its problems, but they&#8217;re being worked out, and overall I&#8217;m quite proud of the site we built.)</p>
<p>However, the really interesting parts of Buzz are all behind the scenes.  The front end was an exercise in the complicated and delicate art of engineering simplicity and eliminating redundant effort.  Even in the face of exacting requirements and changing specifications, we ended up releasing a site that performs well and is relatively easy to work on.  On some level, I feel like it was my <dfn title="The kid you have and treat really nicely to make up for their older sibling that turned into a drug addict due to your shoddy parenting">karma baby</dfn> for some of the complicated monstrosities that I&#8217;ve left in my wake as a developer.</p>
<p>But, with Buzz behind me, creating and maintaining yet another website has gotten a bit old.  Nothing wrong with that work, but I&#8217;m done with it for now.  Time to do something else.</p>
<h2 id="opensocial_and_mash_ups">OpenSocial and Mash-ups</h2>
<p>Douglas Crockford has called mash-ups <a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?tag=mashups" class="external">One of the most exciting features of WEB 2.x</a>, and I couldn&#8217;t agree more.  The vision of the web from the get-go was a distributed platform for innovation.  As client technology and usage advanced, dynamic features followed naturally.  The ability to mix-and-match data and functionality into new applications is a <em>very</em> exciting prospect.</p>
<p>However, like so much potential innovation on the web, this effort is severely hampered by the same system that makes it possible.  The browser Dom was designed by committee, and the committee didn&#8217;t actually meet for a while, and the members of the committee were trying to kill one another.  Throughout the browser wars, IE and Netscape introduced features in a frantic arms race to try to shut one another out of the browser market.  Many of those features were not really ready for prime time, and many others probably should have been wiped off the whiteboard and never made it into the code.</p>
<p>On the plus side, browsers and web pages were able to innovate much faster than the w3c&#8217;s crawl.  Much of the time, the &#8220;official&#8221; specs only included a feature because a few browsers had already implemented it and it was in widespread use.  That speed got us to where we are, but lots of important things were sacrificed or forgotten along the way.  Among the missing: a proper permission model.  Same-domain restriction works to some degree, but it makes mashups trickier and there are still big holes.  In particular:</p>
<ul>
<li>Scripts run with the same access permission as the page that invokes them, even if they&#8217;re hosted elsewhere.</li>
<li><abbr title="XML HTTP Request">XHR</abbr> calls can&#8217;t get data asynchronously from external domains.</li>
<li>The Dom is one big global that all scripts have access to.</li>
<li>Iframes restrict permission, but they&#8217;re a pain to work with.</li>
</ul>
<p>Sadly, this means that mash-ups are faced with the choice of:</p>
<ol>
<li>Only accessing public data, lest some untrusted third party get ahold of something it shouldn&#8217;t have.</li>
<li>Running the risk that a third party might steal some data.</li>
</ol>
<p>Essentially, mash-ups are thus restricted from really doing anything interesting.  PayPal or Amazon or Yahoo&#8212;-that is, sites with money and interesting private data&#8212;-could never risk exposing their data to a mash-up.  Their visibility, and the value of the private data they hold, makes them prime targets for attack.  And, since they have money, and visibility, they&#8217;re also prime targets for lawsuits if a user was damaged by a mistake.</p>
<p>OpenSocial represents a concerted effort by some very big players on the web to make severely interesting and useful mash-ups not just a reality, but common and relatively easy to create and host.  API layers will sit between the developer and the browser, and between the developer and the container page, allowing them to code as if it&#8217;s 2099 and the browser is sane.  It&#8217;s no small task.  When Hao asked me to join the team, and told me what they were doing, my initial reaction was <q>Well, it might end up a total failure.  But it&#8217;ll be one hell of a fun problem to work on.  I&#8217;m in.</q></p>
<p>There were hints and rumors that Yahoo was doing something with OpenSocial a while back.  (We were.)  But, the main reaction to the press release really should be <q>Well, spluh.</q>  Yahoo&#8217;s all about social; it may have started with indexing the web into searchable categories, but some of its earliest and most popular applications are mail, instant messaging, and groups.  Yahoo&#8217;s all about open; we invest countless developer-hours into the open source technology that we use.  Yahoo has a lot to gain from a more exciting social internet; when the ocean rises, the bigger fish benefit the most.</p>
<h2 id="warnings_wrapped_in_compliments">Warnings Wrapped in Compliments</h2>
<p>For a month or so, I&#8217;ve been transitioning off the Buzz team and onto the team that&#8217;s doing the OpenSocial container stuff.  As people found out that I was joining that team, I heard this line a lot from various people: <q>Oh, thank god.  They really need a good front-end.</q></p>
<p>There&#8217;s a very flattering element to that, and I&#8217;m not trying to brag.  Objectively speaking, I know I&#8217;m good at what I do.  I love doing it, and I work hard at it, and that&#8217;s just what happens when you work hard at what you love.  No magic at all.</p>
<p>At the risk of sounding like a falsely modest blow hard, though, on a more moment-to-moment basis in my own world, I focus on many of my own failings that others rarely see, and I am always very impressed when someone solves a problem that I was stuck on.  I often feel like I&#8217;m still new at Yahoo, and on some very insecure level, I&#8217;m waiting for them to find out that I&#8217;m just playing at this stuff and tell me I&#8217;ve fooled the real adults for long enough, and it&#8217;s time to go home.</p>
<p>But I <em>am</em> good at what I do.  It&#8217;s real.  These skills are rare, and they&#8217;re worth money.  When others acknowledge it, though, I kind of feel embarrassed and get all &#8220;aw, shucks, twern&#8217;t nuttin&#8217;&#8221; and find myself unable to make eye contact.  (A few times, this reaction has evoked a <q>No, seriously!  I mean that!</q> which just adds to the effect.)</p>
<p>So, the flip side of that comment&#8230; yes yes, I&#8217;m a great webdev, blah blah, but say that first part again?  It&#8217;s a bit like hearing, <q>Oh, thank god they picked you to wrestle that giant raptor.  He&#8217;s been killing one guy after the next, so I&#8217;m really glad that they finally picked someone who can take him down.</q>  Why couldn&#8217;t it have been <q>That&#8217;s great!  There&#8217;s a lot of great talent on that team, I&#8217;m sure you&#8217;ll fit right in!</q></p>
<p>Well, that&#8217;s the cards that life deals you sometimes.  Impossible problems are the most fun, anyway.</p>
<p>And I&#8217;ve found that there really are a lot of talented developers on this team.  Some more have joined it recently.  I&#8217;m really happy to be able to be working in this group.</p>
<h2 id="meetings">Meetings</h2>
<p>Somehow, I managed to work myself into a role on this team where most of my time is spent in meetings.  Some of them were soul-sapping and boring, as meetings can be sometimes, but lately, they&#8217;ve seemed to focus more and more on solving front-end problems at an architectural level.  After almost every one, someone whips out a phone to take a picture of the whiteboard, lest our valuable work be lost to the eraser.  </p>
<p>Additionally, I&#8217;ve been attending the <a href="http://developer.yahoo.com/yui/" title="Yahoo User Interface" class="external">YUI</a> team meetings, as they&#8217;re interested in knowing what they can do to aid Yahoo&#8217;s big bets.  Through that, and by virtue of working on a product that promises to push the limits of what the browser can safely do, I&#8217;m finding myself consulted because Microsoft is asking Yahoo what we think of the IE 8 beta, and what we&#8217;d like to see in it.  I&#8217;ve been asked to teach a CSS class for the next round of incoming junior/trainee webdevs (Jukus, as they&#8217;re called).  I&#8217;m meeting with other groups and helping to figure out what OpenSocial means for their product&#8217;s context, and how they&#8217;ll use what we&#8217;re building.  Today, we&#8217;ve got a meeting at the Googleplex.</p>
<p>It certainly looks like success.  And the pay is pretty good.  The product is fun and open and creative.  It&#8217;s one puzzle after another.</p>
<p>But, I&#8217;m feeling a bit envious of the other developers I talk to who get more time to write code.  From Tuesday to Thursday of last week, iCal was booked solid from 11-5 every day, I ended up in ad hoc discussions about things (or dealing with email) until about 7 or 8 each night.</p>
<p>I have tried hard not to become a manager at Yahoo.  Perhaps a management path is in my future somewhere, but right now, it just seems like a job I would not enjoy.  Programming is a very social activity if you&#8217;re doing it right.  With a new team and a new product, there&#8217;s plenty of architecture and designs to figure out, and I&#8217;ll be coding again soon enough.</p>
<p>I hope.</p>
<h2 id="hey_one_more_thing8230">Hey, one more thing&#8230;</h2>
<p>We have openings for great engineers and webdevs.  If any of this sounds like something you&#8217;d be interested in, <a href="/contact/" class="internal">let me know</a>.  I&#8217;m 100% serious.  Javascript and PHP experts, we need you.  Yahoo is, in my opinion, one of the best places for talented engineers to work.  They generally treat their employees very well, and this is a product that is just full of fascinating puzzles.  </p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/04/opensocial-meetings-and-success/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Needed: chpass, finger, and pw for the web</title>
		<link>http://foohack.com/2008/03/needed-chpass-finger-and-pw-for-the-web/</link>
		<comments>http://foohack.com/2008/03/needed-chpass-finger-and-pw-for-the-web/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 17:00:38 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Bright Ideas Not Yet Realized]]></category>

		<category><![CDATA[The Business]]></category>

		<guid isPermaLink="false">http://foohack.com/2008/03/needed-chpass-finger-and-pw-for-the-web/</guid>
		<description><![CDATA[<p>It&#8217;s <a href="http://radar.oreilly.com/archives/2007/03/sfearthquakes-on-twitter.html" class="external">been said</a> that the best startups take a popular Unix command and bring it to the web.  But there are a few that are poorly represented.  I understand that I may be making a bad career move by discussing this openly on a blog, but quite honestly, my desire as a consumer for a satisfying product is enough to risk&#8212;-nay, <em>hope</em>&#8212;-that someone else makes a million dollars doing this before I get a chance to.</p>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s <a href="http://radar.oreilly.com/archives/2007/03/sfearthquakes-on-twitter.html" class="external">been said</a> that the best startups take a popular Unix command and bring it to the web.  But there are a few that are poorly represented.  I understand that I may be making a bad career move by discussing this openly on a blog, but quite honestly, my desire as a consumer for a satisfying product is enough to risk&#8212;-nay, <em>hope</em>&#8212;-that someone else makes a million dollars doing this before I get a chance to.</p>
<p>I&#8217;m thinking specifically  <a href="http://www.freebsd.org/cgi/man.cgi?query=chpass&amp;sektion=1" class="external">chpass</a>, <a href="http://www.freebsd.org/cgi/man.cgi?query=finger" class="external">finger</a>, and <a href="http://www.freebsd.org/cgi/man.cgi?query=pw&amp;sektion=8" class="external">pw</a>.</p>
<p>I know what you&#8217;re thinking.  There have been a few forays into this arena.  MySpace, Facebook, and Plaxo come to mind, not to mention whatever else some MBA has stuck to a &#8220;social network&#8221; this week.  (<q>It&#8217;s just like a regular duck, but this one swims around the lake <strong>and</strong> lets you put all your friends in a list! I&#8217;ll be rich!</q> The sad thing isn&#8217;t that he thinks it; the sad thing is that he just might be right.)</p>
<p>The social-for-the-sake-of-being-social sites tragically miss the point.  I have resisted getting a Facebook account for a few years now, and even deleted my MySpace account.  They seemed to require a lot of time and effort doing basically nothing, and didn&#8217;t give me what I really want.</p>
<h3 id="managing_data_is_not_necessarily_enjoyable">Managing data is not (necessarily) enjoyable</h3>
<p>I <strong>hate</strong> managing contact lists.  The worst contact list, the one that is the hardest to manage, is the one in my head.  Every day I get older, I get worse at remembering phone numbers, and I like to know who&#8217;s calling me.  I like to see your picture when you call, see your real name when you email.  I want my email program or my phone to know who you are when I start to type the three letters of your name that I can remember off-hand, even (especially!) if you&#8217;re someone I don&#8217;t talk to often.</p>
<p>That&#8217;s why I shelled out $40 for <a href="http://radar.oreilly.com/archives/2007/03/sfearthquakes-on-twitter.html" class="external">Missing Sync</a> so that my phone and computer can share an address book.  I have an Applescript program sitting on my back burner that will sync any contacts I add in Adium into this same collection, and even look up their contact details from Yahoo&#8217;s corporate intranet (since most of the time, they&#8217;re work mates.)  Automated replication is still not great, but it eases the pain of managing multiple lists.</p>
<p>Facebook and MySpace are software platforms designed around the premise that <em>managing</em> a contact list is fun.  And it can be in that 12-23 age range where we attempt to define ourselves and carve out our place in the world through our social connections.  That&#8217;s a key demographic for advertisers.  Good for you, Facebook.  But if I wanted to spend all this time managing my friendships, I&#8217;d have more of them in real life.  <small>Ooh, burn! i mean&#8230; hey, wait a second..</small></p>
<p><a href="http://plaxo.com" class="external">Plaxo</a> is actually a pretty good approximation of what I&#8217;d like to see, at least on the &#8220;managing contacts&#8221; side of things.  Granted, I&#8217;ve been spamvited to their service by half a dozen people I hardly know, which is a classic example of &#8220;let&#8217;s be viral&#8221; gone horribly horribly wrong.  But their product offering is pretty close.  You get one contact list online, and it syncs with other areas.  It&#8217;s unfocused since they&#8217;ve added &#8220;Pulse&#8221; (basically an RSS aggregator for your other web profiles), but still pretty good.</p>
<p>However, even Plaxo misses a key point, and makes several fatal flaws.  I&#8217;m actually talking about a profile and contact management system that is much grander.</p>
<h3 id="dry_8212_what_changed"><abbr title="don't repeat yourself">DRY</abbr> &#8212; What Changed</h3>
<p>In a relational database or data map, the idea is to keep a piece of data in only one place, and store the relationships between entities rather than making multiple copies.  Most contact management systems, from a little black book to the cell phone contact list to Outlook to Plaxo, fail to implement this simple principle.  Instead of making each node in the network keep track of all the data about all the other nodes in which it is interested, instead let each node control its own data, and store links to the nodes in which it is interested. </p>
<p>In the old days of land lines, the phone book was enough.  If you knew someone&#8217;s name and city, you could get their phone number and, perhaps, their street address by performing a simple lookup.  Each user had the option to control how much information was shared with the public.  Until the autodialer came to telemarketing, the abuse rate was limited by the cost of using the technology.</p>
<p>Today, each person has many more pieces of contact information, and the cost of abuse is virtually zero.  There is no way in hell that I&#8217;d let anyone publish my actual cell phone number, and once an email address is exposed, it&#8217;s basically useless.  Spam fighting is an arm&#8217;s race, and an unfair one even for Google and Yahoo to fight.</p>
<h3 id="why_we_need_those_commands_on_the_web">Why we need those commands on the web</h3>
<p>Back to my original point: <a href="http://www.freebsd.org/cgi/man.cgi?query=chpass&amp;sektion=1" class="external">chpass</a>, <a href="http://www.freebsd.org/cgi/man.cgi?query=finger" class="external">finger</a>, and <a href="http://www.freebsd.org/cgi/man.cgi?query=pw&amp;sektion=8" class="external">pw</a>.</p>
<dl>
<dt>chpass</dt>
<dd>
<p>add or change user database information</p>
<p>In other words, manage my info in one place.</p>
</dd>
<dt>finger</dt>
<dd>
<p>The finger utility displays information about the system users.</p>
<p>In other words, look up the information that other have made available.</p>
</dd>
<dt>pw</dt>
<dd>
<p>create, remove, modify &#038; display system users and groups</p>
<p>In other words, specify who has permission to what.</p>
</dd>
</dl>
<p>Many large companies have some sort of online system like this.  At Yahoo, it&#8217;s the almighty Backyard, the corp website that started as a list of email addresses and grew into a full-scale intranet with contact lookup and LDAP access.  (It also features conference room booking and documentation searching and plenty of other handy things.  But mostly, it&#8217;s still all about the mega employee contact list.)</p>
<p>You manage your own profile, and make sure that your numbers and whatnot are up to date.  No one else ever has to worry about how to contact you, because it&#8217;s all in one place.  However, that only works because access to the backyard system is tightly limited to current employees, so abusing the system would entail serious consequences for the abuser&#8217;s reputation (and career).</p>
<p>In other words, we have finger and chpass, but pw is being done manually by the <abbr title="Human Resources">HR</abbr> department, which limits the possible size of the network considerably.</p>
<h3 id="abuse_prevention_is_extremely_non_trivial">Abuse Prevention is Extremely Non-Trivial</h3>
<p>The easier it is to use a networked contact management system, the easier it is to abuse.  The more useful it is for you and your friends and associates, the more useful it is for spammers and scammers.  Already, we have to keep our email addresses hidden from strangers.  Imagine how much worse it would be if a <abbr title="Porn, Pills, and Credit">PPC</abbr> pusher could just e-finger &#8220;isaac.schlueter&#8221; and have my home address, email, phone number, instant messenger alias, birthday, and photo.  Yes this is <em>exactly</em> the sort of information that I&#8217;d like to easily share with everyone else.</p>
<p>Everything that has been done so far in the area of email spam, while impressive and necessary, is <strong>fundamentally</strong> inadequate.  As long as it remains profitable for a spammer to send out 100 billion emails every day, it will happen.  Any attempts to prevent or avoid this behavior run counter to the incentives of the market; which is to say that it&#8217;s a bit like building a dam of sand and expecting to stop the Mississippi.  Won&#8217;t happen.  A bigger dam will take longer, but eventually, they&#8217;ll all crumble.</p>
<p>In order to truly divert human behavior, the <em>incentive</em> must be dealt with at the source.  Direct attacks against the offenders (ie, shutting down their accounts) are not effective in the long run (they just get new accounts.)  Negative incentives, such as putting spammers in jail, are not going to be effective in the long run, because it doesn&#8217;t push the <em>cost</em> of spamming up high enough.  John Q. Spammer doesn&#8217;t think he&#8217;ll be the one to get caught, and he&#8217;s probably right.</p>
<p>I don&#8217;t claim to have this bit of the system figured out, not by a long shot.  But I have a few ideas.</p>
<h4 id="irl">IRL</h4>
<p>In real life, we meet a lot of people, and many of them can and do annoy us by contacting us in unwanted, if mostly harmless, ways.  The foul smelling man who stops babbling for a second to ask me for a quarter.  The smiling woman who shoves a tract at me and tells me I&#8217;m going to hell.  Sadly, the list goes on and on and on.</p>
<p>However:</p>
<ol>
<li>It&#8217;s easy to size someone up quickly, because:</li>
<li>Annoying people build a reputation for being annoying, because:</li>
<li>They&#8217;re real people and you can see who they are.</li>
</ol>
<p>There are still, of course, the violent offender and the con man.  However, in real life, direct attacks incur a high degree of risk, due to the chances of being caught or retaliated against, and so law enforcement has a relatively easy time keeping serious criminals in check.  And those looking to do you harm by gaining confidence and taking advantage of it, well, they&#8217;ll always be around, but they&#8217;re pretty rare and the reputational aspects keep them somewhat in check as well.</p>
<h4 id="so8230">So&#8230;</h4>
<p>Entrance into this global open personnel file would require that an account be tied to a single real person, who doesn&#8217;t have any other account in the system.  Accounts that are not &#8220;backed&#8221; by some kind of reliable identity are only given some kind of limited provisional access&#8212;-perhaps they can email a user through the system, but they cannot get the user&#8217;s &#8220;real&#8221; email address, and users would be able to deny access altogether to unidentified strangers if they chose.</p>
<p>Identification is itself a non-trivial task requiring a high degree of trust from the web site.  Even if you know it&#8217;s 100% secure, being asked for your date of birth, <abbr title="Social Security Number">SSN</abbr> or passport, and a major credit card is a tall order.  Without biometrics, it must come down to discrete bits of information at some point, which can be (and often are) faked.</p>
<p>A rinky-dink fly-by-night startup can&#8217;t hope to achieve this level of trust quickly.  And, without getting a critical mass of users, the value proposition to new users is a lot tougher.</p>
<p>The company to build this system would need:</p>
<ol>
<li>A huge base of existing users and preferably their contact details, too.</li>
<li>A strong reputation for protecting user data.</li>
<li>Impressive engineering resources and domain knowledge in the areas of spam protection and social networking.</li>
<li>A serious commitment to open APIs that help the web as a whole.</li>
</ol>
<h3 id="if_it8217s_not_everywhere8230">If it&#8217;s not everywhere&#8230;</h3>
<p>&#8230;then it may as well not be anywhere.  The goal of this system would be to revolutionize contact management the same way that email and hypertext revolutionized written communication.</p>
<p>Just as email works in any email client, and web pages work can be viewed by any browser, the APIs provided by this system would have to be completely open.  Any application must be allowed to interact with them, both to change data and fetch it.</p>
<p>In order for it to work, and <em>really</em> have the effect that I&#8217;m talking about, there must be absolutely no lock-in, no up-sell, and reasonably liberal rate limits.</p>
<h3 id="">$$$</h3>
<p>How does something like this make money?  That&#8217;s an open question, and a big one, probably part of the reason why I&#8217;m still pushing bits in a day job and not out getting VC to build this thing.  <small>I also happen to really like what I do at that day job.</small></p>
<p>Maybe it would have to be something built under the Apache foundation or some other OSS group, and sponsored by donations of capital and resources from some major players in the online social arenas.  Maybe there&#8217;s some clever way in which smaller users and early adopters get the API for free, but then charge everyone else.</p>
<h3 id="who_could_do_this_what8217s_going_on_now">Who could do this?  What&#8217;s going on now?</h3>
<p><a href="http://openid.net" class="external">OpenID</a> is a great start, but what we really need is an open <em>profile</em> and open <em>contact list</em> system, and OpenID doesn&#8217;t provide that.</p>
<p>Google&#8217;s <a href="http://code.google.com/apis/opensocial/" class="external">Open Social</a> is an interesting product, but the more I read about it, the more I think it&#8217;s not quite low-level enough to really deliver on what I&#8217;d like to see here.  While it promises to expose social data to third-party applications in an API that could be consistent across social websites, it doesn&#8217;t fully address the issue of being able to manage contact data in a distributed way.</p>
<p>As I said above, the company to do this will need: </p>
<ol>
<li>A huge base of existing users and preferably their contact details, too.</li>
<li>A strong reputation for protecting user data.</li>
<li>Impressive engineering resources and domain knowledge in the areas of spam protection and social networking.</li>
<li>A serious commitment to open APIs that help the web as a whole.</li>
</ol>
<p>Yahoo has all four of these, but that whole China escapade has damaged Yahoo&#8217;s reputation in the eyes of many users.  Of any company on the web, however, Yahoo has perhaps the most to gain from such a system and a lot of resources and domain knowledge to throw at the problem.</p>
<p>Even if they only share user information when presented with a subpoena, that means that using this system exposes my information to governmental intrusion, which is deeply problematic.  In order to be truly trustworthy, a stronger commitment to protecting privacy needs to be in place than just words on a corporate press release.  The officers of the company to provide this service should enter into a binding agreement that they will not knowingly expose user information, even in the face of governmental pressure.</p>
<p>Like I said, I don&#8217;t have all the answers to this product.  But I know that, as a user, I&#8217;d be absolutely delighted to see something like this take hold.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/03/needed-chpass-finger-and-pw-for-the-web/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Yahoo! Buzz</title>
		<link>http://foohack.com/2008/02/yahoo-buzz/</link>
		<comments>http://foohack.com/2008/02/yahoo-buzz/#comments</comments>
		<pubDate>Thu, 28 Feb 2008 03:19:01 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Pushed Into the Wild]]></category>

		<guid isPermaLink="false">http://foohack.com/2008/02/yahoo-buzz/</guid>
		<description><![CDATA[I&#8217;m a little behind in posting this, since it&#8217;s been live and in the media for a while now. Go check it out: http://buzz.yahoo.com

It took a lot of work to pull this thing together.  Monday night was the craziest month of my web development career, culminating in this tweet posted as I finished pushing <small><a href="http://foohack.com/2008/02/yahoo-buzz/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a little behind in posting this, since it&#8217;s been live and in the media for a while now. <a href="http://buzz.yahoo.com" class="external">Go check it out: http://buzz.yahoo.com</a></p>
<p>It took a lot of work to pull this thing together.  Monday night was the craziest month of my web development career, culminating in <a href="http://twitter.com/isaacschlueter/statuses/759204492" class="external">this tweet</a> posted as I finished pushing the last packages out into production.  <small>I managed to ignore the page that came in 5 hours later. I wonder if it was some kind of subconscious self-preservation that made me leave my phone on vibrate when I finally went to bed.  Sorry bout that, Trang.</small></p>
<p>And despite the <a href="http://valleywag.com/357006/screenshots-of-yahoo-buzz-a-digg-competitor" class="external">rather disappointing leak</a>, it seems to have been <a href="http://www.readwriteweb.com/archives/why_yahoo_buzz_is_a_brilliant_idea.php" class="external">pretty well received</a>.</p>
<p>We worked really hard on this project, and while it&#8217;s definitely still a &#8220;beta&#8221;, the feature set is enough to be interesting, in my opinion.  All in all, this has been a highly rewarding product to be a part of, and I&#8217;m extremely proud to have been a part of the team that built it.  </p>
<p>I&#8217;m in the process of moving onto a different team, and I have mixed feelings about the transition.  On the one hand, the team I&#8217;m joining is doing some truly ambitious and interesting things, and it&#8217;s more in the direction that I want to go.  I&#8217;ve been starting to get tired of building one web site after another, and this will be an opportunity to do something much more in the &#8220;web application&#8221; direction.  On the other hand, the Orion team is one of the best groups of developers I&#8217;ve ever worked with, and it&#8217;s sad to leave them.</p>
<p>But that&#8217;s the joy of working at a company like Yahoo&#8212;if you get bored of doing one thing, then there&#8217;s always something else, and no matter which team you&#8217;re on, there are lots of top-notch developers among your coworkers.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/02/yahoo-buzz/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Foo Hack Redesign 3.0</title>
		<link>http://foohack.com/2008/02/foo-hack-redesign-30/</link>
		<comments>http://foohack.com/2008/02/foo-hack-redesign-30/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 17:00:41 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[CSS]]></category>

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

		<guid isPermaLink="false">http://foohack.com/2008/02/foo-hack-redesign-30/</guid>
		<description><![CDATA[So, it started out as just a few font changes.  I&#8217;d been growing less and less pleased with Trebuchet MS, and had found a few cases where it broke the militant line-height rules I&#8217;d set for this site.  In general, I felt that it was too crowded, and the gray hash textured background <small><a href="http://foohack.com/2008/02/foo-hack-redesign-30/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>So, it started out as just a few font changes.  I&#8217;d been growing less and less pleased with Trebuchet MS, and had found a few cases where it broke the <a href="/2007/08/marching-to-a-vertical-cadence/" class="internal">militant line-height rules</a> I&#8217;d set for this site.  In general, I felt that it was too crowded, and the gray hash textured background was (in my opinion) a contrived and artless approach.</p>
<p>I&#8217;m not a very understanding end-user when it comes to this site.  The Foo Hack design team got fed up with my complaints, and decided to give in and make some changes.</p>
<p>Feature creep is a bitch when you have a deadline.  For personal projects, there is no deadline, and so a bit of feature creep is fun, within reason.  That&#8217;s a big part of the reason why I have so many back-burner projects that are almost finished; just as I near the finish line, I decide that it needs a little more, or another project gets more interesting for a while.  So, on to what changed.</p>
<h3>Fonts</h3>
<p>I was a computer geek first, but when my dad replaced our DOS home computer with a Windows 3.1 box, I fell in love with fonts.  I can waste an afternoon surfing the web downloading fonts that I&#8217;ll probably rarely (if ever) use.  Web design is about 90% typography, and it is an art that blends strict perfectionism and fluid acceptance in a beautiful way.</p>
<p>For the main body text, I wanted something subtle and easy on the eyes.  Something that would let the writing speak in the voice that I intend, without getting in the way.  For the &#8220;small&#8221; items of diminished importance (asides and things in <code>&lt;small&gt;</code> tags) I wanted a serif font with a very thin ex measurement, so that the text could &#8220;feel&#8221; smaller without altering the line-height.  For the headings, I wanted a rounder, more open font that could evoke a sense of boldness without being too heavy.  Subheadings and meta items (the date, &#8220;comment&#8221; link, etc.) should use the same font, but with less letter space and a subtler color.</p>
<p>For the body text, I decided to go with Helvetica, the classier old-world cousin of Arial.  I was initially pleased with the results.</p>
<p>Cliché though it may be, Times New Roman was the perfect choice for the diminished items.  It&#8217;s very light, yet still fairly readable, and when italicized, it practically disappears.  I was already using it for that reason, but since I don&#8217;t love <abbr title="Times New Roman">TNR</abbr> all that much, I was willing to entertain other possibilities.</p>
<h3>If Helvetica is so great, why do I see Arial?</h3>
<p>A problem came up when I noticed that the line-height was getting messed up whenever a TNR inline element would wrap to the next line.  I figured out the problem.</p>
<p>Let&#8217;s say you have font A and font B.  You create a block-level element using font A.  Then, you have an inline element using font B, which wraps to the next line.</p>
<p>If A and B don&#8217;t put their letters on exactly the same point in the line-block, then the line-height will <em>adjust</em> up or down, as the next line is set by the position of the letters in B instead of the position of letters in A.  Since the B element isn&#8217;t a block-level element, it won&#8217;t create a whole new block, and will have the effect of adding or removing a few pixels from the overall height of the A element.</p>
<p>To correct this problem, and still have 2 fonts sharing the same block-level element, you need to find two fonts that have exactly the same vertical letter placement on the line block.</p>
<p>I&#8217;m not exaggerating when I say that I created a test page and exhaustively tested every combination of serif and sans-serif fonts on my Mac.  It took about a week.  There was only one combination that worked.</p>
<p>Arial and Times New Roman.</p>
<p>Ah, compromise, my old nemesis. You strike again.  Not willing to give up the line-height strictness, I gave in and decided to use Arial instead of Helvetica.  On the bright side, Windows users were mostly going to see Arial anyway, and they&#8217;re both tried and true web-safe fonts.  And, at typical screen resolutions, it&#8217;s hard to tell the difference anyway.  But still, it&#8217;s a bit of a sore point.</p>
<h3>Gotham, Large and Small</h3>
<p><a href="http://www.typography.com/fonts/font_overview.php?productLineID=100008" class="external">Gotham</a>, the masterpiece homage to urban signage by <a href="http://www.typography.com/" class="external">Hoefler &amp; Frere-Jones</a>, is quite possibly the best font ever devised.  It&#8217;s open and confident even when it&#8217;s not bold, balanced and practical.  I went with this as the headings, and it also was the best candidate for the smaller informational bits.  (After all, it seemed fitting to put navigational links in a font designed for signage.</p>
<p>The downside of such a perfect font is that it&#8217;s not free.  It would be fantastic if Apple or Microsoft were to license Gotham for their respective operating systems, but I don&#8217;t see that happening any time soon.  Those that don&#8217;t want to install Gotham will see Century Gothic (if it&#8217;s installed, most likely because they got it bundled with Microsoft Office), or something in the Lucida family.</p>
<h3>Accentuate the Important, Diminish the Rest</h3>
<p>I brought down the contrast a bit, and did away with the background graphic.  Some color was sprinkled around to help create a meaningful mental model of each page.  I got the idea for the categories above the titles from <a href="http://randsinrepose.com" class="external">Rands in Repose</a>, one of my favorite regular reads.</p>
<p>The default set of post meta info that Wordpress provides is far more than necessary.  I got rid of everything that didn&#8217;t directly benefit the goals of conversing with the world through this blog.</p>
<h3>Comments</h3>
<p>It seems awkward that my comments should have a blue left border, and reader comments are unadorned.  Simply using random colors wouldn&#8217;t do.  So, I wrote a function that will hash a string into a color value.  A simpler hash would have sufficed, but I wanted more control over the range of colors that it selects, and <code><a href="http://php.net/rand" class="external">rand()</a></code> was a good fit.  So, your comment will always have the same color (unless you use a different email address, of course) and all the colors will be in a particular mid-range of luminosity that is bold, but not overpowering.</p>
<p>I&#8217;ve already run into a few situations on this blog where I felt that threaded comments would have been helpful. However, the threaded forum-style comments would be complex and counterproductive.  I grabbed a standard threaded-comment plugin, and tweaked it to replace the interface with a few hyperlinks.  Since conversations are more naturally many-to-many, I&#8217;d like to implement something along the lines of what <a href="http://1976design.com/blog/archive/2003/11/12/comments/" class="external">Dunstan Orchard used to have on his blog</a>, but doing that the right way means a bit more investment, and this project was dangerously close to being back-burnered forever.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/02/foo-hack-redesign-30/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Going Fast, Frankenstein, and Refactoring</title>
		<link>http://foohack.com/2008/01/going-fast-frankenstein-and-refactoring/</link>
		<comments>http://foohack.com/2008/01/going-fast-frankenstein-and-refactoring/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 17:00:48 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Broken]]></category>

		<category><![CDATA[Code Beauty]]></category>

		<category><![CDATA[Code Ecosystems]]></category>

		<guid isPermaLink="false">http://foohack.com/2008/01/going-fast-frankenstein-and-refactoring/</guid>
		<description><![CDATA[Very soon now, the project that has consumed my days for the last 6 months will go into public beta.  It's too early to pop the champagne, and that's not what this post is about.  However, the newness of this project is worth pointing out for the following reason: We're <em>already</em> planning a fairly major refactoring effort to take care of a lot of code rot that has crept into the designs.



That's right.  We haven't released anything, and there's already enough bloat to justify spending at least 2 weeks cleaning it up. <small><a href="http://foohack.com/2008/01/going-fast-frankenstein-and-refactoring/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>Very soon now, the project that has consumed my days for the last 6 months will go into public beta.  It&#8217;s too early to pop the champagne, and that&#8217;s not what this post is about.  However, the newness of this project is worth pointing out for the following reason: We&#8217;re <em>already</em> planning a fairly major refactoring effort to take care of a lot of code rot that has crept into the designs.</p>
<p>That&#8217;s right.  We haven&#8217;t released anything, and there&#8217;s already enough bloat to justify spending at least 2 weeks cleaning it up.</p>
<p>Of course, due to the pressures of market, and the morale effects of delaying the release, we&#8217;re buttoning up what we have now as much as possible, and planning to work on the refactor once the beta is out there.  It may actually help a lot, since the gigantic firehose of traffic that Yahoo! points at sites has a way of helping even the most egotistical of developers realize that their clever baby needs some serious surgery.</p>
<p>This post is going somewhere, I swear, but I can already tell it&#8217;s going to take me a while to get there.  Go get some coffee and a snack and come back.  I&#8217;ll wait.</p>
<h3>Build Fast</h3>
<p>In my opinion, the core of good software development methodology comes down to two basic questions that should be asked daily:</p>
<ol>
<li>What portion of your time is spent focused on the task of creating software?<br />
		(That includes planning, discussion, and thinking as well as coding, provided that these non-coding activities are focused and aimed at creating software.)</li>
<li>Does it work today?<br />
		(If you don&#8217;t know, then you are full of Fail.  Get on that right away.)</li>
</ol>
<p>I call this the <strong>Go Fast</strong> method.  The goal is to efficiently create software with <strong>minimum long-term cost and maximum long-term benefit, without driving away your best talent.</strong>  <small>(Have I got the attention of the business and product people in the audience?  Good.  Please stay for the rest of the show.)</small></p>
<p>I know that someone out there is bound to point out the obvious parallels between my &#8220;go fast&#8221; methodology and Agile, and maybe they&#8217;re right.  To the extent that Agile accepts these premises as important, it is correct.  But I&#8217;m claiming that <em>everything else</em> stands or falls based on how it affects these questions.  Stand-ups, planning meetings, org charts, IDEs, frameworks; they&#8217;re all only as good as their effect on the principles of speed and stability in development.</p>
<p>If you&#8217;re developing software properly, you should be creating software that does something as soon as possible, and keep it up as much of the time as you can.  Until there&#8217;s something to look at, you&#8217;re just spinning your wheels.  Nowhere is this more true than on the web.  Photoshop comps don&#8217;t break in different browsers.  Product presentation decks don&#8217;t &#8220;feel klunky&#8221; when pieces load out of order.  Grand visions promise to solve all your problems and make you biscuits for breakfast, but they don&#8217;t deliver.</p>
<p>You make software for a living?  So make software, already.  You wanna build a website?  What&#8217;s stopping you?  You don&#8217;t have designs yet?  Build the parts that you do have.  <a href="http://www.codinghorror.com/blog/archives/000809.html" class="external">Always be releasing,</a> even if your actual release date is months away.</p>
<p>Build the core, and grow the other pieces up around it.  Every minute spent waiting, instead of actually building something, is worse than wasted.  When you live in the code day by day, it becomes a part of you.  You learn how the pieces work, and the knowledge is automatic.  When you get too far from it, it becomes foreign, like driving a car for the first time.</p>
<p>The agilistas call this &#8220;shippable code.&#8221;  In my opinion, that&#8217;s a horrible term.  The vast majority of code that I&#8217;ve seen released into the wild was not even close to what I&#8217;d call &#8220;shippable,&#8221; but it got shipped just the same.  Most of the time, the prototypes leading up to the release were significantly worse.  Some agilistas are quick to point out that &#8220;shippable&#8221; doesn&#8217;t always really mean &#8220;that you would actually ship it.&#8221;  Sorry, but drivable means that you can drive it, and drinkable means that you can drink it, and flyable means that you can fly it, so if &#8220;shippable&#8221; doesn&#8217;t mean &#8220;you can ship it,&#8221; then they picked a bad term.</p>
<p>I suspect the ambiguity is intentional on some level.  I think the claim that &#8220;Agile makes software faster&#8221; is a myth.  Agile methodologies, used in moderation by a well-balanced team of dedicated and talented individuals, <em>do</em> tend to result in higher quality software, greater management visibility, and a happier bunch of people than any alternative, but that means that the overall development time can be significantly longer.  And if you&#8217;re not on a well-balanced team of dedicated and talented individuals, then no methodology is going to save that sinking ship, so dust off the CV and bail out ASAP.  But I digress, and besides, you already know that I think <a href="/2007/11/agile-scrum-sucks-but-so-do-the-alternatives/" class="internal">Agile sucks</a>.</p>
<p>I prefer to call it a running prototype, or an integration environment, or anything else that&#8217;s more, well, accurate.  &#8220;Shippable code&#8221; tells overeager managers that they can just press &#8220;stop&#8221; at any point and ship what they&#8217;ve got.  Nice dream land, hot shot, but it doesn&#8217;t actually work quite like that.  Nevertheless, a good integration development environment, where everyone&#8217;s code gets placed and which is subjected to regular updates and testing&#8212;that&#8217;s important, almost as important as CVS and a decent build script, and for a lot of the same reasons.  If the team&#8217;s code isn&#8217;t conversing regularly, then the team may as well not be, either.  The best way to prevent blockages is to prevent assumptions; the best way to prevent assumptions is to check them <em>every single day</em>.  So: <q>Does it work today?</q></p>
<p>Completion feels good.  Getting something that works feels good.  That&#8217;s why we got into this business.  Because, despite all the pain and frustration and work that goes into developing software, <a href="http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html" class="external">The High</a> here is about as good as it gets.</p>
<p>You don&#8217;t get that waiting.  You don&#8217;t get that talking.  You get that when you are immersed in building something.</p>
<p>From a team dynamic perspective, I can&#8217;t even find words to express how it makes people gel when we each do our little pieces, and plug them in, and see a site come up with data and styles and behavior and images and everything.  It&#8217;s a pretty marvelous event that makes everyone even more eager to get to work.  If you&#8217;re a web developer, don&#8217;t wait for your designer or back-end engineer to give you what you need.  Make an unstyled page with dummy data, if you have to, but make <em>something</em> on day 1 if possible.  Then make a list of what you need.  When everyone can see their effect on the product, it&#8217;s amazing how fast they tend to deliver.</p>
<p>Going fast and pushing to milestones also forces everyone on the team to prioritize.  There may be plenty of features that might be <em>nice</em> to implement, but if speed is a priority, then it forces you all to work on the things that really <em>need</em> to be implemented.  By raising red flags whenever something doesn&#8217;t work, the whole project stays in sync most of the time, and assumptions never get too far out of whack.  But, of course, that&#8217;s not the whole story.</p>
<p><img class="alignright" src='http://foohack.com/blog/wp-content/uploads/2008/01/victor-frankenstein.jpg' alt='Gene Wilder as Victor Frankenstein' />Software development is a lot like building Frankenstien&#8217;s monster.  You start out with a pile of useless ugly pieces, and try to turn it into something beautiful.  Along the way, it&#8217;s a monstrosity, and tends to get uglier as you tack new bits onto it.  Then it kills people.</p>
<p>In Mary Shelly&#8217;s classic, everyone Victor loves is killed by the eloquent and sensitive creature, who was turned evil by his creator&#8217;s neglect and hatred.  If software could walk and talk, how many developers would still be alive today?</p>
<h3>Slow Down</h3>
<p>Don&#8217;t build Frankenstein&#8217;s monster, or at least, don&#8217;t figure you&#8217;re &#8220;mostly done&#8221; once it walks and talks, as the strict waterfall process proposes.  Going fast is important, and necessary.  You can&#8217;t fix pure ideas very easily, because it&#8217;s hard to see what&#8217;s wrong with them.  Write the code.  But know that it&#8217;s going to have to be rewritten, possibly several times.  Plan for it, and keep it in the back of your mind.</p>
<p>The hazard of moving quickly is that we tend to go with the <em>easy</em> choice, rather than the <em>good</em> choice.  Adding one more method onto the class I&#8217;ve already got is easier than creating a whole new class; nevermind that it doesn&#8217;t really &#8220;fit&#8221; with what this type of object is supposed to be doing.  Do that once, and it&#8217;s probably a lot simpler and clearer than any alternative.  Do that 50 times, and you end up with a <a href="http://en.wikipedia.org/wiki/God_object" class="external">theological problem</a>, or something else <a href="http://en.wikipedia.org/wiki/Code_smell" class="external">equally pungent</a>.</p>
<p>This will happen.  Every time.  If you don&#8217;t have some downright embarrassing shit-tastic WTF-worthy code lurking in your project&#8212;I mean, the kind of thing where you see a bug report go to your coworker, and you say to him, <q>Oh, I&#8217;ll take that one, I know that feature</q>, but really, you&#8217;re saying <q>Please don&#8217;t look at that code, or at least, if you do, please don&#8217;t judge me</q>&#8212;then you probably weren&#8217;t going fast enough.  The remarkable thing isn&#8217;t that this team has produced a product that &#8220;already&#8221; needs a cleanup; the remarkable thing is that we all seem to recognize that we need to clean things up, before it&#8217;s blown up in any serious way yet.  That&#8217;s why I&#8217;m thankful to be on the team that I am.  I&#8217;ve heard it said that the difference between a good programmer and a bad programmer is that a good programmer feels pain when he looks at ugly code he&#8217;s written, while a bad programmer thinks everything he&#8217;s done is great.</p>
<p>I used to be proud of every bit of code I&#8217;d written, like a two-year-old who just learned how to use the potty.  Then I grew up a little bit, and realized that my shit stinks, and hoped no one would ever see it.  I&#8217;ve grown up a little more, and realized that everyone shits, so there&#8217;s nothing to be ashamed of.  I try to work towards a point where my actually shit doesn&#8217;t stink at all, but I&#8217;m not all that hopeful about that.  The fecality of this line of metaphor, while a bit disgusting, is meant to highlight an important point.</p>
<p>You want to create code that is nice to be around?  Do your best to build quality in from the start.  The more you learn, the better you&#8217;ll be at it, especially if you manage to code yourself into some truly awful maintenance nightmares, where you can&#8217;t walk away and can&#8217;t blame anyone else.  But no matter how good you get, it&#8217;s still gonna stink most of the time.  <a href="http://scribesonic.com/Blog/Archive/2007/10/04/Coding-Horror-Interview.aspx" class="external">Everyone</a> writes <a href="http://thedailywtf.com/Articles/What_Could_Possibly_Be_Worse_Than_Failure_0x3f_.aspx" class="external">bad code</a>.  So fix it.</p>
<h3>Refactoring</h3>
<p>Wikipedia <a href="http://en.wikipedia.org/wiki/Refactoring" class="external">says</a>:</p>
<blockquote cite="http://en.wikipedia.org/wiki/Refactoring"><p>Refactoring neither fixes bugs nor adds new functionality. Rather it improves the understandability of the code or changes its internal structure and design, and removes dead code, to make it easier for human maintenance in the future.</p></blockquote>
<p>To relate to the twin principles of software development, &#8220;Go fast&#8221; and &#8220;Does it work?&#8221;, refactoring is not important early on.  Surely, doing things as close as possible to The Right Way is usually a big help.  But <a href="http://www.jwz.org/doc/worse-is-better.html" class="external">The Right Way</a> almost always flies in the face of the &#8220;Go Fast&#8221; maxim.</p>
<p>I&#8217;ve been privy to a few refactoring projects, I think I can safely say that almost every single one was an utter disaster.  Without naming names, here&#8217;s how a few turned out:</p>
<ol>
<li>Lead engineer spent 3 months internally redesigning a feature with the intent of making it more extensible in the future.  Released.  Numerous bugs and problems.  When I left the company, it was still unstable.  <strong>FAIL</strong></li>
<li>The product has grown into an amalgam of junk, and no one knows how to maintain all the disparate pieces. Can&#8217;t add features easily.  Needs to be re-architected.  [[numerous planning meetings]] OK, management says we have 2 months, so let&#8217;s just add another layer on it, change how it looks, and call it a day. Result was even more disorganized and difficult to extend.  <strong>FAIL</strong></li>
<li>#2, again, with new people driving it, who insisted that the last ones were all wrong.  Same result.  <strong>DOUBLE FAIL</strong></li>
<li>Repeat, <em>again</em>.  <strong>TRIPLE SUPER DUPER FAIL</strong></li>
<li>Last, but oh, so certainly not least, there were all the refactorings that didn&#8217;t even make it to a real execution.  The times when the development team was so fed up that they pushed to change things, and were told repeatedly that they could get to that just as soon as the next project got done&#8212;there was always a &#8220;next project.&#8221;  <q>It works now, what&#8217;s the matter with it?</q>  To the best of my knowledge, of three teams where I saw this pattern, (a) one company no longer exists, (b) another company lost all their best talent, and (c) in the third case, the team dissolved and everyone moved onto other projects (it was at Yahoo!, so it&#8217;s not like they were going to go under.)  For failing before they&#8217;d even gotten started, these refactoring projects are <strong>QUADRUPLE UBER KAMEHAMEHA FAIL!!!</strong></li>
</ol>
<p>I strongly doubt that any of these cases were rare.  In fact, I think they&#8217;re the norm.</p>
<p>It&#8217;s easy to cite bad management, and in a few of the above cases, management was to blame.  They put a high premium on getting new features, without recognizing the hidden costs down the road of dealing with the increasing instability.  However, the fact that I&#8217;ve come to realize is that most developers don&#8217;t really understand <a href="/2007/06/the-most-important-things-they-don%e2%80%99t-teach-in-compsci-101-but-should-maintainability/" class="internal">maintainability</a>, and thus, tend to completely miss the point of what the purpose of refactoring should be.  As a result, their attempts at refactoring end up being worse than failures, because they are interpreted as success.</p>
<p>I did get to see one significant refactoring project that I&#8217;d consider a success.  It was done in an under-the-radar sort of way, simply because it was the only way to add new features to a product that had grown frightfully unwieldy.  Also, I&#8217;ve seen and done a lot of small scale refactorings that were executed well and increased the quality of the product as a result.  (These, as the Wikipedia article mentions, are usually referred to as simply &#8220;cleaning up&#8221; the code base.)</p>
<p>Refactoring can only be justified in the &#8220;Go Fast&#8221; methodology on the condition that it makes a more stable product, thus enabling developers to more efficiently create working software.  Elegance is not an end in itself.  The end goal is a working product, and <a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html" class="external">code is the enemy</a>.  The vast majority of software development is about modifying an existing product.  The short-term memory of a human is limited and fleeting.  The less information that must be held in mind to understand a given section of code, the more quickly code can be modified, the lower the likelihood of introducing bugs with any given change.  So, there is, ultimately, only one purpose that Refactoring should serve:</p>
<div class="important">
<p>Be more obvious.</p>
</div>
<h3>Love Your Monster</h3>
<p><a href="http://foohack.com/blog/wp-content/uploads/2008/01/frankenstein1831inside-cover.jpg" class="alignleft" title='Inside cover of the original 1918 Frankenstein by Mary Shelly.'><img src='http://foohack.com/blog/wp-content/uploads/2008/01/frankenstein1831inside-cover.thumbnail.jpg' alt='Inside cover of the original 1918 Frankenstein by Mary Shelly.' /></a>Victor was so consumed by his desire to create something new that he ended up rushing the job and not thinking ahead.  When his creature opened its eyes, he feared it, and fled, and tried to hide from his sin.  Shunned from the world, the creature asked Victor to make him a companion.  When his request was denied, he proceeded to destroy everything Victor loved.</p>
<p>The moral of the story: Don&#8217;t ignore the ugliness you create.  It will find you.</p>
<p>Refactoring should make the code simpler.  Complexity is the demon that we fight in writing code.  It is the enemy.  It opens the doors to bugs; it increases the difficulty in fixing problems and adding features; it raises the learning curve for new developers.  Sadly, a lot of refactoring seems to make code more complex rather than less.</p>
<p>In my opinion, there are a few guidelines that work well when changing around existing code.  These guidelines apply equally well when creating new code, but since it&#8217;s harder to see the whole picture in that scenario, mistakes and shortcuts are more forgivable.</p>
<ul>
<li>There should be as few layers as possible, and no fewer.</li>
<li>There should be as few objects as possible, and no fewer.</li>
<li>Each object should be as small as possible, and no smaller.</li>
<li>Each object should know as little as it needs to, and no less.</li>
<li>Each piece should have a job, and should stick to it.</li>
<li>Comments should be mostly unnecessary.</li>
</ul>
<p>Refactoring isn&#8217;t about using the coolest object oriented tricks that you just learned.  It&#8217;s not about making the code &#8220;more abstract.&#8221;  Abstraction is a necessary evil, in my opinion, not a feature.  Like Victor, it&#8217;s easy to get wrapped up in testing out new discoveries.  Most of us got into this job because we like playing with new puzzles, and that&#8217;s a great thing.  But one of the most satisfying puzzles is to reduce the complexity of an implementation without reducing the problems that it can solve.</p>
<p>I&#8217;m a big fan of &#8220;comment-driven development&#8221;.  That is, write out the pseudo-code in comment form first, stubbing out the functions that need to be implemented.  It helps to separate the design and implementation phases, since it can be hard to do both simultaneously.  As implementation kinks are getting worked out, the design might change slightly, but it helps to have the comments there as a guide to what I was originally thinking.  Once a module moves into a more stable place, the comments are a liability.  At best, they&#8217;re clutter; at worse, misleading.</p>
<p>I like using those comments to clean up the code as well.  The process goes like this:</p>
<ol>
<li>Read through the code, starting at the entry point, and opening each file as it&#8217;s referenced.</li>
<li>If a section of code has a shit-ton of comments, then it needs work.  If it&#8217;s clean, just make sure it makes sense.</li>
<li>Make sure the comments match what the code is doing.</li>
<li>Remove any incorrect comments (comments that are lying.)</li>
<li>If the code isn&#8217;t understandable without the comments, then dig in and clean it up.  Rename methods, sort things better, etc.</li>
<li>Remove any and all implementation-related comments.  Those are dangerous.</li>
<li>Repeat until the file is almost comment free, and understandable.</li>
</ol>
<p>I&#8217;m not so certain on the common refactoring claim that it should not change any existing functionality.  Sometimes, this is of vital importance.  However, there are plenty of times where the feature set of a bit of code simply needs to be trimmed or revised.  For public-facing APIs and products, either the functionality should not be changed, or interfaces should be publicly deprecated long before they are actually removed.</p>
<p>For internal code, or APIs that are only used by a small number of consumers, my favorite approach is to just change it, and then see what breaks.  This should never be done in a way that affects customers, of course, but in a development environment, it&#8217;s quite appropriate to just change the back-end, and then update the front-end once it&#8217;s fixed.  Defensive coding is a good practice, but <em>overly</em> defensive coding, where errors are not surfaced at all, can hide problems that may turn up later in unexpected ways.</p>
<p>Don&#8217;t bother refactoring something you just wrote.  You&#8217;ll only make it worse.  You have to wait until you don&#8217;t remember how it works before you look at it again, or else you won&#8217;t be able to appreciate the difficult bits.  If you don&#8217;t have time for that, then make someone else do it, and tell them to be as harsh as possible.</p>
<h3>Ego</h3>
<p>As <a href="http://www.softwarequotes.com/ShowQuotes.asp?ID=605&amp;Name=Weinberg,_Gerald_M.&amp;Type=Q" title="&quot;they&quot; == Gerald M. Weinberg" class="external">they say</a>, <q>No matter what the problem is, it&#8217;s always a people problem.</q>  The first and most important step in any refactoring effort is to detach our egos from our code.  This is even more of an issue if something you wrote is being refactored by someone else, or worse, if you are refactoring someone else&#8217;s code.</p>
<p>I&#8217;ve worked hard to develop a pretty good understanding of software development.  I&#8217;ve found that the technology side is easy&#8212;on the human side, I still have a lot to learn, and probably always will.  Like a lot of geeks, I didn&#8217;t really get into the whole &#8220;social&#8221; thing in a serious way until I was almost an adult, and even today, I tend to focus on The Project and keep my distance from the rest of the world.  So, I suppose I don&#8217;t know the best way to handle this part of the problem.</p>
<p><abbr title="Tim Berners-Lee">TBL</abbr>&#8217;s classic recommendation to be <q>loose in what you accept, and strict in what you send</q> seems to apply well to this case.  On a healthy team, everyone is committed to a successful product, and leaves their egos at home when they come to work.  Code is passed around and everyone seeks as much input as possible.  On a dysfunctional team, everyone&#8217;s sense of self-worth is tied up in the appraisal of their work by others&#8212;which has the twin effect of making them overly sensitive to criticism, and overly critical of their teammates.</p>
<p>It&#8217;s natural to put up resistance to the prospect of your code being modified.  After all, you wrote it that way for a reason.  Sit down with the other developer, and try to hash out the best approach.  If arbitrary decisions have to be made, explain that the best approach is to make them consistently.  Don&#8217;t focus on the problems in their code, but rather on the need for consistency and abstraction throughout the product.</p>
<p>If someone won&#8217;t listen to reason, frankly, the only solution I&#8217;ve ever found is to either leave or wait for them to.  Hopefully they&#8217;re a contractor or something, so you can just wait, and do your best to isolate and minimize the damage as much as possible in the meantime.  If not, then the issue should be escalated, if only because it&#8217;s polite to tell your manager that their ship is in danger of sinking.</p>
<h3>Oh, right, that book&#8230;</h3>
<p><a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/isaacschlcom-20" class="alignright"><img src='http://foohack.com/blog/wp-content/uploads/2008/01/refactoring.thumbnail.jpg' alt='Refactoring, by Martin Fowler' /></a>I read <a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/isaacschlcom-20" class="external">Refactoring</a> about 5 years ago, but I&#8217;ve been meaning to pick it up again, since I&#8217;ve gotten a fair amount of real-world development experience since then, and have seen my share of dismal failures.  But this isn&#8217;t supposed to be a <a href="http://books.slashdot.org/article.pl?sid=08/01/09/1515240" class="external">book review</a>, so I won&#8217;t review it in any detail.  It&#8217;s a good read, though, and I highly recommend it, even though it is mostly in Java, and seemed (to me at least) to simply highlight a lot of design problems inherent in the Java language that lead inevitably to bloated over-sized code.  But that&#8217;s a post for another day.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2008/01/going-fast-frankenstein-and-refactoring/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Surgical Team or Motley Crew of Adventurers?</title>
		<link>http://foohack.com/2007/12/surgical-team-or-motley-crew-of-adventurers/</link>
		<comments>http://foohack.com/2007/12/surgical-team-or-motley-crew-of-adventurers/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 19:10:17 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[Code Ecosystems]]></category>

		<category><![CDATA[The Business]]></category>

		<guid isPermaLink="false">http://foohack.com/2007/12/surgical-team-or-motley-crew-of-adventurers/</guid>
		<description><![CDATA[The Dungeons and Dragons party is, I believe, a much better metaphor for the modern programming team than Mills' and Brook's surgical team.  In what has been called the <q cite="http://www.seldo.com">geekiest thing every written</q>, I catalog some different character classes and explain their corollary roles in a web development team.  I suspect that other types of programming teams have similar roles. <small><a href="http://foohack.com/2007/12/surgical-team-or-motley-crew-of-adventurers/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve read <a href="http://www.amazon.com/dp/0201835959/?tag=isaacschlcom-20" class="external">The Mythical Man-Month</a> lately (at <a href="/2007/10/required-reading-for-web-developers-the-fountainhead-by-ayn-rand/#comment-132" class="internal">Geoff&#8217;s suggestion</a>, among others) and it&#8217;s great.  I definitely recommend it highly to anyone in the software development field.</p>
<p>In particular, I was struck by the idea of Mills and Brooks that software development could be done more effectively by a &#8220;surgical team.&#8221;  That is, the experienced lead developer writes all or most of the code, and is supported by a team of people to make him more effective.  While this is perhaps an effective way to capitalize on the significant difference between excellence and mediocrity in coders, it seems to me that most of the jobs on the team are today either (a) made obsolete by technological advancements, or (b) best done by specialists who float between teams.  For example, Yahoo! has some of the best Javascript and CSS &#8220;language lawyers&#8221; in the world&#8212;but does every team really need one?  The need for a full-time toolsmith has been all but completely surpassed by the customizability of workstations and the availability of many high-quality tools for coding and such.</p>
<p>The nature of software development has changed somewhat as well.  We aren&#8217;t writing assembly code any more; not only do we have high-level languages, in my current project, there are no fewer than 9 different languages in use, 10 if you count regular expressions, which we all use quite frequently.  <a href="#ft1" id="n1" title="MySQL, PHP, Javascript, HTML, CSS, Bash, Perl, XML, yinst, regular expressions. Actually, 11 if you count Apache config directives." class="internal">[1]</a>  We aren&#8217;t all creating the same kind of stuff.  Thus, there is a strong need for <em>all</em> of us to be experts, surgeons if you will, in our respective areas.  In addition, the non-coding jobs require their own sort of specialized focus.</p>
<p>It occurred to me that this division of labor, where everyone depends on everyone else but everyone has a very different job, is more like a Dungeons and Dragons party than a surgical team.  Each member plays a vital but remarkably different role, each owns what they do, and each is the team&#8217;s expert in what they do.  As a webdev, I get consulted about front-end concerns, and am quick to ask a back-end engineer about things that touch their domain.  UI questions are decided by the interaction designer; questions of product features are handled by the product manager, etc.  I suspect that this is not unique to software for the web; a similar metaphor exists (or at least, <em>could</em> exist) for application software.</p>
<p>The best D&amp;D parties are a bit formulaic, but that&#8217;s simply because a certain distribution of talents tends to be most adaptable to the most different kinds of problems.</p>
<h3>Fighter</h3>
<p><img src="http://myskitch.com/isaacschlueter/fighter-20071202-031522.jpg" alt="fighter" width="300" height="365" class="alignright" /> Not the flashiest or most prestigious role, Fighters have the lowest barrier to entry.  They accumulate experience quickly, and don&#8217;t have a lot of class bonuses.  (Until 3<sup>rd</sup> Edition made them into action heroes, that is.)  But their simplicity belies a focus and strength that is crucial.  The fighter is the guy in the party that protects the more &#8220;thinky&#8221; types from anything that might get in their way.  There can be honor and satisfaction in bashing orcs one at a time.</p>
<p>On a web development team, there are two archetypes that sometimes satisfy this role.  The first is the diligent code monkey who might not be the most ambitious or inventive, but is good at getting things done.  They are perfectly happy to churn through buglists, knocking down whatever they can.  If you show them how to do something, they&#8217;ll make it work however it has to through sheer force of will&#8212;not always fast or elegant, but functional.  When depended upon properly, code monkeys are a great and valuable asset.</p>
<p>Also in the fighter category are the producers who manage the content of the site, use the admin tools, troll for spammers, and do all the other busywork of web site maintenance.  When the programmers have moved on to the next problem, they&#8217;re still working.  Don&#8217;t forget them.  Whenever possible, make their lives easier.  They are the ones that keep your product shiny, so you can continue to be proud to have the URL sitting there on your resume.</p>
<h3>Ranger</h3>
<p>Rangers are good at surviving on their own.  They shun convention and human society. <img src="http://myskitch.com/isaacschlueter/ranger-20071202-031443.jpg" alt="ranger" height="344" width="300" class="alignleft" /> Often a bit wild themselves, they feel more comfortable in the company of nature.  Their chaotic bent can sometimes be a liability in an adventuring party, but their wide-ranging knowledge makes them hard to discount.  They are fiercely independent and difficult (if not impossible) to tame.</p>
<p>In a programming team, this is the quintessential hacker.  Most mashups are created by a single ranger acting alone.  They are great at creating new things, and no browser quirk or network irregularity will stand in their way.  On the other hand, they don&#8217;t always follow convention, and have a tendency to create overly clever code that is unintelligible to anyone who follows in their wake.  Thus, they have to be watched closely lest they venture off.</p>
<p>I&#8217;ve learned a lot of great tricks and techniques from the Ranger programmers I know.  I&#8217;m always a bit envious of their free approach to things, but I guess I&#8217;m just too timid to abandon convention completely.  Make sure that you understand their code before you try to adapt it to your own ends&#8212;wild animals turn vicious when handled improperly.</p>
<h3>Paladin</h3>
<p><img src="http://myskitch.com/isaacschlueter/paladin-20071202-031508.jpg" alt="paladin" width="300" height="435" class="alignright" /> The paladin is the character class with the most stringent requirements.  They must conform to the strictest of moral codes and demanding attribute requirements.  As such, they&#8217;re rare, and respected.  The paladin&#8217;s job is twofold.  As a warrior subclass, he protects the party members from outside threats.  However, he&#8217;s also a healer, and a leader.  Charismatic and compassionate, he holds the party together by negotiating internal conflicts.  Unshakably positive, he nonetheless keeps everyone going with firm conviction in the mission.</p>
<p>The best project managers aspire to paladin-like grace in their roles.  They defend the team from the pressures of management and the monotony of GANT and PERT charts, and make sure that everyone is able to work at their top potential.  When there&#8217;s a problem, they are approachable and always seek a win-win situation.  By being consistently honest and righteous, they earn the respect and admiration of those both below and above them on the management totem pole.</p>
<p>When someone leads like a paladin, you <em>want</em> to get your tasks done and meet your deadlines.  Not because you&#8217;re afraid of the consequences, but simply because their drive and attitude are contagious.</p>
<p>There are some managers that are decidedly un-paladin-like.  Few things are as hazardous on a project as leadership that does not inspire confidence and commitment.  Attitude is everything in a leader.</p>
<h3>Rogue</h3>
<p><img src="http://myskitch.com/isaacschlueter/rogue-20071202-031430.jpg" height="427" width="300" alt="rogue" class="alignright" /> The rogue is a highly adaptable character.  They can pick locks and disarm traps, making them essential in any dungeon-faring party.  Surviving in the streets and cities on his wit and stealth, a rogue comes to know the different factions and groups, and learns to navigate the urban waters.  He knows how to make a buck, how to make a friend, and how to sell, and where to buy.</p>
<p>The product manager takes on this role for a programming team.  They are often the ones who first envision the product and pitch it to management.  Often the only member of a programming team with a business background <a href="#ft2" id="n2" title="Unless the webdev is a business school drop-out, that is." class="internal">[2]</a>, they settle questions of business goals and product requirements.  They make the powerpoint presentations that eventually drive the development of a real software product.</p>
<p>The product manager, like a rogue, also sings the song of the party, talking them up when necessary and interacting with foreign powers <a href="#ft3" id="n3" title="Some teams, of course, have a dedicated business development person, or &quot;BizDev&quot; who handles outside relationships so that the product manager can focus on product development. I realize that I'm blurring the distinction, but I don't think it's a big deal." class="internal">[3]</a>.  If a product requires buy-in from another team, whether it&#8217;s a standards group in the same company or a potential outside partner, these are the people who make the calls and settle the deal.  Their day is usually full of meetings.</p>
<p>I&#8217;ve known some developers who look down on product managers as being less technical.  This is a big mistake.  Their job is every bit as intellectually rigorous as ours, due to the huge amount of information that they need to be able to call forth on demand.  Since they deal with features and requirements that have not even been fully envisioned, and might not exist in any form whatsoever in the market, they are even more in the world of pure thought-stuff than programmers.  Make friends with your product manager, and you&#8217;ll find that they often do actually know their stuff.  And after all, some rogues will stab you in the back if you cross them <img src='http://foohack.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Mage</h3>
<p>The mage is the general purpose wizard.  They are resourceful and possess a broad understanding of all types of magic.  While not specialized in their studies, they are deeply theoretical, research oriented, and possess incredible focus and discipline.  Their power comes from being able to summon a wide variety of spells, but they tend to be weak and vulnerable in the chaos of melee, since they must prepare spells ahead of time.</p>
<p>Many experienced back-end engineers fit into this role.  They tend to prefer structured approaches and strongly typed languages, and produce exceptionally high-quality code. <img src="http://myskitch.com/isaacschlueter/wizard-20071202-031243.jpg" width="300" height="393" alt="wizard" class="alignleft" /> They often have advanced degrees in computer science and are knowledgeable in the intricacies of design patterns and memory management.  They excel in areas that are somewhat regular and predictable, where the environment can be controlled, and the assumptions and edge-cases checked accurately.</p>
<p>Dedicated programming wizards are obviously important on any programming team.  However, as much as &#8220;laymen&#8221; tend to see all software as a form of magic, the truth is that mages are actually pretty rare in the development world.  They are the core of the &#8220;20%&#8221; of developers who truly care about what they create and diligently work to improve their abilities.  Their craft is important to them, and they approach each problem with care and precision.  It is much more than just a way to pay the bills.</p>
<p>While dedication is important, it comes at a price.  Many back-end engineers come to get out of touch with the way that &#8220;normal&#8221; people think and interact with software.  Most are pretty aware of this fact; I once knew an engineer who complained that bugzilla&#8217;s user interface was <q>obviously designed by a database expert</q>.</p>
<h3>Specialist Wizard (illusionist, abjurer, conjurer, etc.)</h3>
<p><img src="http://myskitch.com/isaacschlueter/specialist_wizard-20071202-031311.jpg" width="300" height="421" alt="specialist_wizard" class="alignright" /> These are the wizards that have selected a certain area of magic in which to specialize, at the expense of reduced ability in some other area.  They have the same theoretical focus as a mage, but instead of having a broad understanding of every type of magic, they work to gain a much deeper understanding of a single area.  When it comes to solving that sort of problem, they are the best&#8212;however, in other areas, they may be lacking.</p>
<p>There are many &#8220;specialist wizards&#8221; in the programming world.  Here at Yahoo!, there are teams that focus 100% of their time on developing PHP, or MySQL, or Apache.  (<a href="http://lerdorf.com" class="external">Rasmus</a> comes to mind.)  The &#8220;Paranoids&#8221; team sits in the cubes adjacent to ours, and they work to make sure that all the software at Yahoo! is as bulletproof as possible.  The exceptional performance team does research to help us webdevs make our pages load and run faster.</p>
<p>When you have a hammer, the world can begins to look like a nail.  A MySQL specialist will be tempted to suggest a database schema to solve any problem, even perhaps if the problem would be better solved by some other method.  You may be asking for trouble if you ask them to do something outside their specialization.  However, if you have a certain task that you&#8217;re certain to need, they can be invaluable.  Database optimization is a highly developed science, and it&#8217;s not always easy or simple.  Good programmers are rarely security experts (or even security knowledgeable!)  </p>
<p>If you aren&#8217;t likely to have a lot of problems in their specialty, it&#8217;s often better to consult with a specialist only if and when they&#8217;re necessary.  That way a single specialist can service multiple different teams.</p>
<h3>Sorcerer</h3>
<p>Sorcerers are similar to mages in the types of spells that they can cast, but instead of preparing spells from a spellbook, they simply select from the spells that they know, calling them when needed.  As such, they tend to be much more spontaneous.  However, they do not cultivate the discipline or depth of understanding of the wizards, and so they are limited in the number of spells that they can learn.  The sorcerer excels in areas that are uncharted, and their spontaneous approach to magic allows them to quickly adapt to any situation, no matter how unpredictable.</p>
<p>The sorcerer is the perfect corollary to the webdev, <abbr title="also known as">aka</abbr> the front-end engineer.  Web browsers are a constantly moving target, with each behaving a little differently and new versions being released all the time. <img src="http://myskitch.com/isaacschlueter/sorceror-20071202-031341.jpg" height="425" width="300" alt="sorceror" class="alignleft" /> While programming patterns and the &#8220;right&#8221; ways of doing things can be useful, they are often too bulky for Javascript that has to be delivered, parsed, and executed on demand.  Essentially, the webdev creates software in an environment where the rules often make no sense; where the code has to work on different platforms with conflicting requirements; where speed and features are both must-haves.</p>
<p>I&#8217;ve only recently heard of any colleges that make any serious attempt to teach courses on web development.  From what I have heard, the things they teach are pretty bad&#8212;at best out of date, at worst outright harmful.  Most professional web developers that I&#8217;ve met didn&#8217;t learn their craft in school.  Like the sorcerer, they simply picked up their craft as they could, and learned techniques by studying &#8220;in the wild&#8221;; that is, by viewing source and reading websites and trying things out.</p>
<p>I&#8217;ve said before, it takes a certain kind of crazy to want to write software in the browser.  You have to love the chaos and enjoy pulling out tricks and coming up with new hacks to work around impossibly ridiculous requirements.  At the same time, unlike the ranger&#8217;s free-wheeling wildness, the team&#8217;s sorcerer must have enough discipline to tame the chaos and create software with whatever degree of stability he can, in order to help create a functional and stable site.</p>
<p>It can be a challenge at times to find stability and see the bigger picture and not write code for a single case.  Yes, yes, that hack made it work in Safari.  Lovely.  But it&#8217;s also going to be a nightmare to maintain, or you just ruined the accessibility.  Trade-offs are always present, and as far as I can tell, only experience and a lot of mistakes can teach you how to choose wisely.</p>
<h3>Cleric</h3>
<p>Diligent and committed to the ethos of their higher power, the cleric summons heavenly forces to do his bidding.  By making himself an instrument of the divine, he can accomplish great things.  A cleric&#8217;s power comes from their will and common sense (in D&amp;D, this is the Wisdom score), as opposed to the cleverness and wit that Wizards rely on.  The cleric has the power to vanquish undead through the force of their convictions, and their healing spells make them a must-have for any party.</p>
<p><img src="http://myskitch.com/isaacschlueter/cleric-20071202-031607.jpg" alt="cleric" height="395" width="300" class="alignright" /> In a programming party, this is the role of the <abbr title="Quality Assurance">QA</abbr> tech.  These noble souls must possess tenacity and diligence far beyond what is normal or sane.  They must have the conviction and tenacity to insist that every test case be faithfully executed, even if it&#8217;s &#8220;impossible&#8221; that this-or-that change would have caused a regression.  When they see something in the product that doesn&#8217;t look right, they must get to the bottom of it, carefully catalog the event, and enter it into the bug queue.  They help banish the skeletons by exposing them to the light, no matter where they may try to hide.</p>
<p>Many a programmer, close to a deadline, has remarked with exasperation, <q>Jeez, %$!@# QA keeps making me revisit this thing, I fixed that already!</q>, only to find, when they go through the steps in the bug report, that yes, it <em>is</em> indeed broken.</p>
<p>While they may seem difficult or inefficient or outright stubborn at times, they&#8217;re vital.  Their wisdom is a balance to the programmers&#8217;<noscript>Certaines se réfèrent à des <a href="http://www.glavaflex.com/casino-gratuit-liste.html" class="external">casino gratuit</a> qui ne jette pas frappé le mur opposé comme &#8220;Mellenberg Rolls.</noscript> wit, and they keep teams from burning up.  Budget plenty of time for QA.  Start it early.  Get someone who knows what they&#8217;re doing, and use a proper bug tracking system.  Your customers won&#8217;t thank you for it, but they&#8217;ll certainly come to hate you if you don&#8217;t.</p>
<h3>Druid</h3>
<p>Free from any affiliations or alignment, the druid transcends the simple human existence to become one with the natural world.  Unlike the clerics who request their power from a deity, the druid opens themselves up to be nature&#8217;s instrument.  It is an understatement to say that they know about the wild world; they understand the ways of the animals and plants intuitively and instinctively.  Always seeking the way of balance and harmony and simplicity, they do not try to change or restrict the chaos of nature, nor do they rebel against the order that sometimes comes out of that chaos.</p>
<p><img src="http://myskitch.com/isaacschlueter/druid-20071202-031538.jpg" alt="druid" height="347" width="300" class="alignleft" /> Designers are called by many names in our industry.  <abbr title="User Experience Designer">UED</abbr>s, Visual Designers, User Interface Architects, <abbr title="Human Computer Interface">HCI</abbr> Specialists, Interaction Designers, <abbr title="Information Architect">IA</abbr>s.  (Indeed, these roles are somewhat different, as the task of designing the user interface has many facets.)  Whatever they&#8217;re called, their job is to understand the expectations and habits of people they&#8217;ve never met, and shape the product into something that will fit the user&#8217;s mental model.  At the same time, they must understand how those models change in the face of new problems and new solutions, and be able to adapt their software properly.</p>
<p>Like the druid, the UED must be free from any biases that may impede their ability to find the best solution for the user, even if that sometimes means that they may take issue with business objectives.  (If the business goals and the user goals cannot both be met, then the product is in real trouble, anyhow!)</p>
<p>Part of the UED&#8217;s task is to map out the competition&#8217;s sites, to determine where this new product fits into the current ecosystem and how the target market&#8217;s expectations may have already been set.  They must sometimes balance the &#8220;ideal&#8221; way of doing something with the &#8220;common&#8221; way of doing it, simply because users have been trained in a certain way.</p>
<h3>More Similarities</h3>
<p>A lot of the same characteristics that make up a good party are also true of a good programming team.</p>
<ol>
<li>A team should have enough members to get the job done, and no more.</li>
<li>Each member should know his role, and enjoy doing it</li>
<li>Balance is key.  Each part of the task should be accounted for, and no one area should have more resources than is needed</li>
<li>Druids make so-so healers; UEDs are usually pretty good at QA.  A really good sorcerer might be able to handle the magic support if it&#8217;s not too intensive; most webdevs can usually throw some kind of back-end support together.  But, if a certain area of the project is significant, then it&#8217;s worth having someone who knows it best.</li>
<li>Multiclassing can make a character more diverse, but they won&#8217;t increase in levels as quickly.</li>
<li>Treasure should be distributed fairly.</li>
<li>If you have more than one mage (or sorcerer, or cleric, or druid, or whatever), they should either divide responsibilities or one should be in charge.  Same for the roles on a programming team.</li>
<li>It&#8217;s hard for a fighter to know how good a wizard is, or vice versa.  It takes one to know one.  Make sure your team helps interview new hires.</li>
<li>Raising levels and carefully assigning skill points will lead to a more powerful character.  We <a href="http://en.wikipedia.org/wiki/Min-maxing" class="external">min-max</a> in real life, which is why we do it in RPGs.</li>
</ol>
<p>Like most of the essays in <a href="http://www.amazon.com/dp/0201835959/?tag=isaacschlcom-20" class="external">The Mythical Man-Month</a>, the fundamental principles of the surgical team are valid, even if the specific roles are mostly out of date.  Within each class on the adventuring party, you can sometimes see a combination of surgeon and co-pilot; sometimes the co-pilot is unnecessary, or there are two surgeons who divide up the work.</p>
<p>The basic idea of thinking about the programming organization in a creative way is also worthwhile, even if only as a mental exercise.  I&#8217;m sure that there are other metaphors that would work equally well.</p>
<p>In general, I think that the motley crew of adventurers is a lot more fun than the surgical team.</p>
<div class="small">
<h3>Disclaimer</h3>
<p>All images copyright &copy; 2007 Wizards of the Coast.  Please don&#8217;t sue me, WotC!  We love you!</p>
<p>I&#8217;ve taken some liberties with the images used.  The Rogue is actually a Bard.  The Specialist Wizard is some kind of psionicist.  The Ranger is actually a Scout.  I picked more for style than accuracy.</p>
<h3>Footnotes</h3>
<p><a href="#n1" id="ft1" class="internal">[1]</a> MySQL, PHP, Javascript, HTML, CSS, Bash, Perl, XML, yinst, regular expressions. Actually, 11 if you count Apache config directives.<br />
<a href="#n2" id="ft2" class="internal">[2]</a> Unless the webdev is a business school drop-out, that is.<br />
<a href="#n3" id="ft3" class="internal">[3]</a> Some teams, of course, have a dedicated business development person, or &quot;BizDev&quot; who handles outside relationships so that the product manager can focus on product development. I realize that I&#8217;m blurring the distinction, but I don&#8217;t think it&#8217;s a big deal.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2007/12/surgical-team-or-motley-crew-of-adventurers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CSS Modal Dialog that Works Right</title>
		<link>http://foohack.com/2007/11/css-modal-dialog-that-works-right/</link>
		<comments>http://foohack.com/2007/11/css-modal-dialog-that-works-right/#comments</comments>
		<pubDate>Mon, 26 Nov 2007 18:13:04 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[CSS]]></category>

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

		<guid isPermaLink="false">http://foohack.com/2007/11/css-modal-dialog-that-works-right/</guid>
		<description><![CDATA[In my <a href="/2007/11/cross-browser-support-for-inline-block-styling/" title="Cross Browser Support for inline-block Styling" class="internal">last post</a>, I touched on a method to get different browsers to handle the inline-block display style.  I decided to use that on a project that I'm working on now that has a few <a href="http://en.wikipedia.org/wiki/Modal_dialog" class="external">modal dialogs</a>.  Modals are usually done wrong on the web, but I'm pretty confident that this approach does it right.



Feel free to skip all this and go <a href="/tests/vertical-align/dialog.html" class="internal">straight to the example</a>.<small><a href="http://foohack.com/2007/11/css-modal-dialog-that-works-right/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p><em>Note: This method has a few problems.  Scrolling breaks on the iPhone, and the test page has some issues with tabbing through links.  See <a href="http://foohack.com/2007/11/css-modal-dialog-that-works-right/#comment-422" class="internal">my comment</a> below.  A new version will be posted soon. &#8211;i</em></p>
<p>In my <a href="/2007/11/cross-browser-support-for-inline-block-styling/" title="Cross Browser Support for inline-block Styling" class="internal">last post</a>, I touched on a method to get different browsers to handle the inline-block display style.  I decided to use that on a project that I&#8217;m working on now that has a few <a href="http://en.wikipedia.org/wiki/Modal_dialog" class="external">modal dialogs</a>.</p>
<p>Feel free to skip all this and go <a href="/tests/vertical-align/dialog.html" class="internal">straight to the example</a>.</p>
<p>In the application world, creating a modal is pretty straightforward.  Here are some features that every modal window should have:</p>
<ol>
<li>Interaction with the contents of the parent window should be *impossible* until the modal is dealt with.  Scroll-mouse should not scroll the background page, clicking should not click the background page, tabbing should not get you there, etc.</li>
<li>When you dismiss the modal, the parent window should be *exactly* how you left it.</li>
<li>The parent window should be dimmed, or there should be some other indicator that it is currently not available for interaction.  This has the corollary effect of making the modal &#8220;pop&#8221; a bit more.</li>
<li>In a web page, a modal should be constrained within the viewport.  Opening a new window just to show a dialog box is ugly as a bucket of slugs.</li>
<li>The modal should be placed consistently.  If it is not movable, then it should be centered vertically and horizontally.  This positioning should be consistent if the parent window is resized or moved.</li>
<li>The modal should be smaller than the parent window.  If the viewport is resized smaller than the modal, then scrollbars should appear that allow the user to see the rest of the modal.</li>
</ol>
<p>The rule of thumb: The modal should be visible always and in every situation, the parent should be dimmed and preserved.  Almost every modal dialog I could find online broke a few of these rules.</p>
<p>In some, the html and body elements have their overflow set to hidden when the modal is shown, so the current scroll position of those elements is lost.  If you were looking through a list of items, and you brought up a modal dialog related to one of them, then you&#8217;re back to the start of the list when the modal is dismissed. Annoying.</p>
<p>In others,  you CAN scroll the background, but the modal is set to respond to the onscroll event to try to stay in place.  Some of the time, they use display:fixed to behave a little nicer in non-IE browsers.  At worse, you get a jumpy seizure-inducing experience; at best, you accidentally scroll the background and lose your place without realizing it.</p>
<p>It&#8217;s a bit of an edge case, but you do have to handle cases where the modal might be taller/wider than the viewport.  As a test, I tried resizing the viewport down on a bunch of modal approaches.  Vertical centering often doesn&#8217;t do too well unless the contents are smaller than the viewport, so the top and bottom of the modal were cut off.  Unacceptable.</p>
<p>It wasn&#8217;t terribly difficult to create one that obeyed these rules.  Here&#8217;s the approach that I took.</p>
<ol>
<li>Build it with tables.</li>
<li>Replace the tables with divs, and give them the appropriate display:table, display:table-cell CSS rules.</li>
<li>Fret and hack to try to get it to work in IE, unsuccessfully.</li>
<li>IM <a href="http://hedgerwow.com" class="external">another yahoo</a> who has a reputation for being a great webdev hacker.</li>
<li>Adapt what he did to my needs.</li>
</ol>
<p>For the non-IE browsers, it&#8217;s pretty straightforward.  Take the scrollbars off of the HTML and BODY elements, and put them on #body instead.  #modal is a sibling of #body, so when it is 100% height and width, it will cover it up.  Then #modal will overlap the scrollbars of #body, without losing the scroll position.  Also, that means there&#8217;s no need to do any trickery with a negative right margin to try (unsuccessfully, on the mac) to overlap the scrollbars.</p>
<p>Since .overlay element in the modal has a display:table, it will always expand to fit its contents.  .overlay&#8217;s parent is overflow:auto, so if .overlay is too big, it&#8217;ll let you scroll to see the rest.</p>
<p>What this means is that you can&#8217;t cut off the top and bottom of the modal. It&#8217;ll be vertically centered if there&#8217;s room, and if not, it&#8217;ll be flush to the top and scrollable.  Perfect.</p>
<p>For IE it gets trickier.  <a href="http://www.hedgerwow.com/temp/css-vertical-align-center-overlay.html" class="external">Hedger&#8217;s example</a> showed 2 great ideas, though.  Basically, if you have 2 siblings that are display:inline-block, then, in IE at least, the line-block will expand to fit both of them.  So, they both end up being vertically centered to the height of the taller child.  If that taller element is width:0, then you essentially have an arbitrary line-height setter for the inline-block row.  In this case, the height is set to 100%.</p>
<p>The other child will be whatever height it is based on its contents.  If that happens to be taller than 100%, then the line-height will be taller than the viewport.  At that point, the overflow:auto parent shows a scrollbar to let you see the rest.  Identical behavior to the standards browsers!</p>
<p>The second problem arises with IE&#8217;s peculiarities when it comes to percentage heights.  For whatever reason, if you have a position:absolute element, it doesn&#8217;t like to do height:100% unless some parent has a fixed height value, like 500px.  100% of 100% doesn&#8217;t compute, for some reason.  Sadly, that means that the element that does the overlay wouldn&#8217;t be able to properly do its job in IE.  So, instead of using a separate transparent layer with a background image, Hedger used the <a href="http://msdn2.microsoft.com/en-us/library/ms532997.aspx" class="external">DXImageTransform.Microsoft.gradient</a> filter on the modal container itself.  However, since the gradient filter doesn&#8217;t actually prevent interaction with the background, I added a 1 pixel transparent gif as the background image.</p>
<p>I&#8217;d very much like to not use this transparent pixel.  It feels a bit like a spacer gif to me.  But, all in all, it&#8217;s a pretty small price to pay.</p>
<p>I didn&#8217;t bother to tackle the tab-order focus stuff in this little test page, since I wanted to just isolate the stylistic stuff to get it working across browsers.  However, it would be good to put a focus handler on #body, and any time a #body element gets focus, focus the #modal instead.  That way, once you tab off the modal dialog, you&#8217;d get right back onto it.  In the spirit of being friendly to keyboard users, it would also be a good idea to keep track of the currently focused element when the modal opens, and go back to it once the dialog closes.</p>
<p><a href="/tests/vertical-align/dialog.html" class="internal">Here it is</a> for your view-source pleasure.</p>
<p>Please please feel free use this modal.  Life is too short to futz around trying to see the &#8220;cancel&#8221; button that is hiding off the screen so you can go back to reading your page.</p>
<p>Let me know if you can think of any enhancements or find any problems with it.  Those of you in the US, I hope you had a great Thanksgiving.</p>
<h3>Update</h3>
<p>I updated it to add support for focus and blur events.  It works in Firefox, MSIE, and Safari. Opera on the Mac has some really strange behavior regarding focusing on links, and I decided that it just wasn&#8217;t salvageable.  Safari requires a bit of hacking to get the focus stuff to work properly, but I think it&#8217;s acceptable.</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2007/11/css-modal-dialog-that-works-right/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cross Browser Support for inline-block Styling</title>
		<link>http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/</link>
		<comments>http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 17:06:33 +0000</pubDate>
		<dc:creator>Isaac</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[Code Beauty]]></category>

		<guid isPermaLink="false">http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/</guid>
		<description><![CDATA[Inline-block layout solves a lot of problems.  It lets you do some cool stuff previously thought impossible with CSS.  It makes vertical alignment work properly.  And sadly, it's supported pretty badly.  I learned a new approach from <a href="http://blog.hedgerwow.com/" class="external">one of the best insane inventor webdevs I know</a>.  The pieces have been <a href="http://www.google.com/search?q=display%3A-moz-inline-stack%3B+display%3Ainline%3B+display%3Ainline-block%3B+zoom%3A1%3B" class="external">out there for some time</a>, it seems, but I hadn't ever seen this spelled out as simply and elegantly as he did it. <small><a href="http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/" class="internal">...Read More</a></small>]]></description>
			<content:encoded><![CDATA[<p>I learned a new CSS trick from <a href="http://blog.hedgerwow.com/" class="external">one of the best insane inventor webdevs I know</a>.  The pieces have been <a href="http://www.google.com/search?q=display%3A-moz-inline-stack%3B+display%3Ainline%3B+display%3Ainline-block%3B+zoom%3A1%3B" class="external">out there for some time</a>, it seems, but I hadn&#8217;t ever seen this spelled out as simply and elegantly as he did it.</p>
<p>Inline-block layout solves a lot of problems.  It lets you do some cool stuff previously thought impossible with CSS.  It makes vertical alignment work properly.  And sadly, it&#8217;s supported pretty badly.</p>
<p>Mozilla doesn&#8217;t support inline-block at all, but they have -moz-inline-stack which is about the same.  Fair enough, since no one else understands -moz-inline-block, you can just do this:</p>
<p><code class="block css">display:-moz-inline-stack;<br />
display:inline-block;</code></p>
<p>If you put inline-block after -moz-inline-stack, then Moz will start using the &#8220;right&#8221; one <a href="http://developer.mozilla.org/en/docs/Firefox_3_for_developers" title="That is, with version 3" class="external">when it supports it</a>.</p>
<p>IE supports inline-block, but only for elements that are natively inline.  So, if you really want to use inline-block, you&#8217;re restricted to spans and strongs and ems, when a list or paragraph would perhaps make more semantic sense (and also degrade more nicely for non-CSS users.)</p>
<p>However, if you trigger <a href="http://www.satzansatz.de/cssd/onhavinglayout.html" class="external">hasLayout</a> on a block element, and then set it to display:inline, it magically becomes an inline-block in IE!  By using the *property hack (which I love so well), you can hide the display:inline from all non-IE browsers effortlessly.</p>
<p>Here&#8217;s the code, in all its brief loveliness:</p>
<p><code class="css block">display:-moz-inline-stack;<br />
display:inline-block;<br />
zoom:1;<br />
*display:inline;</code></p>
<p>From there, it pays to learn a thing or two about <a href="http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align" class="external">the vertical-align property</a>.  It lets you do lovely things like <a href="/tests/vertical-align/image-labels.html" class="internal">this</a>.</p>
<h3>Benefits</h3>
<p>Inline block elements can be vertically centered like display:table-cell, but they wrap when they get to the end of their parent.  Also, it&#8217;s supported across browsers using this hack, whereas display:table-cell is not supported in IE.</p>
<p>This technique allows for some very interesting layout approaches that would have required a lot of very tricky use of floats previously.</p>
<h3>Caveats</h3>
<p>If an element is inside of an inline block, and lies outside the <a href="http://www.w3.org/TR/REC-CSS2/visuren.html#inline-formatting" class="external">line box</a>, then it won&#8217;t be clickable in Mozilla.  Give the child element <code>position:relative</code> to correct the problem.</p>
<p>Elements treated this way will have <a href="http://www.satzansatz.de/cssd/onhavinglayout.html" class="external">hasLayout</a> set in MSIE.  This is a weird and esoteric aspect of MSIE&#8217;s CSS engine that has potentially unforeseen consequences.  Beware.</p>
<p>If an IMG element is directly inside an inline block element in Mozilla, it will stretch to the full width of that element.  Wrap all IMG tags in a block-level container element to avoid the problem.</p>
<p>Since inline block elements wrap and flow like inline content, that means that they also respect white space like words on a page would.  That is, if there is *any* whitespace between two inline-block elements, then a single space will be added between two inline-block elements.  If this causes a problem, you can either remove the whitespace or comment it out like so:</p>
<p><code class="html block">&lt;/div&gt;&lt;!--<br />
--&gt;&lt;div&gt;</code></p>
<p>All in all, the caveats are pretty easy to work around, and the benefits allow for some really cool stuff that would be almost impossible or very difficult otherwise.</p>
<h3>The 2 Faces of vertical-align</h3>
<p>In <a href="/2007/10/top-5-css-mistakes/#p41_vertical_alignment" class="internal">a classic CSS blunder</a>, vertical-align can mean 2 extremely different things, depending on whether an element is display:inline-block or display:table-cell.</p>
<dl>
<dt>table-cell</dt>
<dd>
<p>Align the element&#8217;s <strong>contents</strong> according to the element&#8217;s vertical-align property.  IE, if the cell&#8217;s vertical-align is set to &#8220;middle&#8221;, then vertically center the element&#8217;s contents.  The height and position of the element itself is determined by the containing display:table element.</p>
</dd>
<dt>inline-block</dt>
<dd>
<p>Align the <strong>element</strong> according to the element&#8217;s vertical-align property.  IE, if the inline-block&#8217;s vertical-align is set to &#8220;middle&#8221;, then the element is vertically centered in the line-block.  The height and position of the element&#8217;s contents are determined by the standard block-level flow rules.</p>
</dd>
</dl>
<p>While I personally believe that this was a stupendously bad and confusing approach to take, I believe that the reasoning comes from backwards compatibility.  Inline blocks emulate the behavior of the IMG tag, and the vertical-align CSS property thus mimics the old valign attribute.  Table cells emulate the behavior of the TD tag, and the vertical-align CSS property thus mimics the behavior of the valign attribute on TDs.  In other words, in this way, CSS faithfully reproduces the sloppy errors of HTML.  It would have been better to use two different properties to achieve this effect; after all, vertical-align:baseline hardly makes sense for table cells.  Perhaps the inline-block type of vertical alignment would have been better called &#8220;line-position&#8221; or some such, since it is less like a vertical version of the text-align property.</p>
<p>But, <span class="info" title="paraphrasing Rumsfeld">you write code with the language you have, not the language you wish you had</span>, and CSS is what it is, at least for the foreseeable future.</p>
<p>Recently, I had to achieve <a href="/tests/vertical-align/dialog-table.html" class="internal">an effect</a> that was extremely tricky by standard methods, but extremely easy using tables.  I decided to test out a display:table approach, and then try to hack it into place for IE, since it is the only browser that does not support this approach.</p>
<p><a href="/tests/vertical-align/dialog.html" class="internal">The result</a> uses a fairly large number of DIVs, but still fewer than the straight table approach, and without the semantic rubble of tables.  The dialog is vertically and horizontally centered, but if you resize the viewport too small, the dialog will not be hidden permanently, due to the &#8220;collapse to fit&#8221; nature of the table display style.  Doing this will an inline-block would have been quite a bit more difficult.</p>
<p>For IE, I used the 50/50 hack.  Create a position:absolute element at top:50%.  Then, create a position:relative child at top:-50%.  The negative top rule on the position:relative element will be misinterpreted, and result in a vertically centered box.  The downside is that IE gets a scrollbar if the viewport is less than twice the height of the dialog.  But, that&#8217;s a pretty acceptable down side, in my opinion.</p>
<p>Sadly, unlike with display:inline-block, it doesn&#8217;t look like there&#8217;s any real consistency to support display:table across browsers.  (Except, of course, using table tags.)  You basically just have to hack something for IE that achieves the same effect, and which approach you use varies on the effect you&#8217;re going for.  In this case, I exploited an IE positioning bug to achieve vertical centering, but other situations would require different approaches.  If you&#8217;re doing complex layouts using display:table, which in a perfect world would indeed be a great way to do it, you&#8217;re going to have a lot of work cut out for you hacking away at IE.</p>
<p>Let&#8217;s pray that IE 8 supports display:table!</p>
]]></content:encoded>
			<wfw:commentRss>http://foohack.com/2007/11/cross-browser-support-for-inline-block-styling/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
