<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Journal of a Maker]]></title>
  <link href="http://warrenm.github.com/atom.xml" rel="self"/>
  <link href="http://warrenm.github.com/"/>
  <updated>2011-12-16T23:42:15-06:00</updated>
  <id>http://warrenm.github.com/</id>
  <author>
    <name><![CDATA[Warren Moore]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[UIView Rounded Corners]]></title>
    <link href="http://warrenm.github.com/blog/2010/09/28/uiview-rounded-corners/"/>
    <updated>2010-09-28T14:54:09-05:00</updated>
    <id>http://warrenm.github.com/blog/2010/09/28/uiview-rounded-corners</id>
    <content type="html"><![CDATA[<p>This is just a quick note regarding UIViews and rounded corners.</p>

<p>As you may know, every UIView is backed by a stack of CALayers, a by-product
of the fact that compositing in iOS is managed by Core Animation. This allows
you to configure a custom masking layer on top of the primary backing layer of
a view.</p>

<p>In the past, I&#8217;ve used <a href="http://blog.sallarp.com/iphone-uiimage-round-corners/">Björn Sållarp&#8217;s UIImage categories</a> to redraw
images with corners as needed, with a little bit of custom magic to select
which corners are rounded.</p>

<p>Although it is probably more performant to render an image once than composite
it every time the view draws, being able to instantly select which corners are
rounded is sometimes an affordable luxury. You might disagree, and <a href="https://www.twitter.com/turbotomato">Michael Ayers</a> has done some recent work on squeezing performance out of situations like
this.</p>

<p>But, with the goal of keeping things simple and dynamic in mind, I created a
very small category on UIView that allows you to select a corner radius and a
set of corners to round. The core algorithm is shown below, followed by a link
to the public <a href="http://github.com/warrenm/UIView-RoundedCorners">github repo</a>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">CGMutablePathRef</span> <span class="n">path</span> <span class="o">=</span> <span class="n">CGPathCreateMutable</span><span class="p">();</span>
</span><span class='line'><span class="n">CGPathMoveToPoint</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">nil</span><span class="p">,</span> <span class="n">minx</span><span class="p">,</span> <span class="n">midy</span><span class="p">);</span>
</span><span class='line'><span class="n">CGPathAddArcToPoint</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">nil</span><span class="p">,</span> <span class="n">minx</span><span class="p">,</span> <span class="n">miny</span><span class="p">,</span> <span class="n">midx</span><span class="p">,</span> <span class="n">miny</span><span class="p">,</span> <span class="p">(</span><span class="n">corners</span> <span class="o">&amp;</span> <span class="n">UIViewRoundedCornerUpperLeft</span><span class="p">)</span> <span class="o">?</span> <span class="n">radius</span> <span class="o">:</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="n">CGPathAddArcToPoint</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">nil</span><span class="p">,</span> <span class="n">maxx</span><span class="p">,</span> <span class="n">miny</span><span class="p">,</span> <span class="n">maxx</span><span class="p">,</span> <span class="n">midy</span><span class="p">,</span> <span class="p">(</span><span class="n">corners</span> <span class="o">&amp;</span> <span class="n">UIViewRoundedCornerUpperRight</span><span class="p">)</span> <span class="o">?</span> <span class="n">radius</span> <span class="o">:</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="n">CGPathAddArcToPoint</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">nil</span><span class="p">,</span> <span class="n">maxx</span><span class="p">,</span> <span class="n">maxy</span><span class="p">,</span> <span class="n">midx</span><span class="p">,</span> <span class="n">maxy</span><span class="p">,</span> <span class="p">(</span><span class="n">corners</span> <span class="o">&amp;</span> <span class="n">UIViewRoundedCornerLowerRight</span><span class="p">)</span> <span class="o">?</span> <span class="n">radius</span> <span class="o">:</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="n">CGPathAddArcToPoint</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">nil</span><span class="p">,</span> <span class="n">minx</span><span class="p">,</span> <span class="n">maxy</span><span class="p">,</span> <span class="n">minx</span><span class="p">,</span> <span class="n">midy</span><span class="p">,</span> <span class="p">(</span><span class="n">corners</span> <span class="o">&amp;</span> <span class="n">UIViewRoundedCornerLowerLeft</span><span class="p">)</span> <span class="o">?</span> <span class="n">radius</span> <span class="o">:</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="n">CGPathCloseSubpath</span><span class="p">(</span><span class="n">path</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">CAShapeLayer</span> <span class="o">*</span><span class="n">maskLayer</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CAShapeLayer</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">maskLayer</span> <span class="nl">setPath:</span><span class="n">path</span><span class="p">];</span>
</span><span class='line'><span class="p">[[</span><span class="n">self</span> <span class="n">layer</span><span class="p">]</span> <span class="nl">setMask:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'><span class="p">[[</span><span class="n">self</span> <span class="n">layer</span><span class="p">]</span> <span class="nl">setMask:</span><span class="n">maskLayer</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">maskLayer</span> <span class="n">release</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="http://github.com/warrenm/UIView-RoundedCorners">View code on Github</a>. Feel
free to fork away and send suggestions. MIT License.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Automatically Generate iPhone/iPad Icons at All Required Sizes]]></title>
    <link href="http://warrenm.github.com/blog/2010/06/18/automatically-generate-iphoneipad-icons-at-all-required-sizes/"/>
    <updated>2010-06-18T16:00:32-05:00</updated>
    <id>http://warrenm.github.com/blog/2010/06/18/automatically-generate-iphoneipad-icons-at-all-required-sizes</id>
    <content type="html"><![CDATA[<p>With the advent of the iPhone 4 Retina Display, iOS application developers
have an <a href="http://mrgan.tumblr.com/post/708404794/ios-app-%0Aicon-sizes">even larger task</a> when it comes to creating the various sizes of icons they need for
their applications. In summary, here are the icon sizes and where they&#8217;re
applied:</p>

<ol>
<li><strong>57x57</strong> - iPod touch, iPhone, iPhone 3G, iPhone 3GS main screen</li>
<li><strong>29x29</strong> - iPod touch, iPhone, iPhone 3G, iPhone 3GS app settings and Spotlight, iPad settings</li>
<li><strong>72x72</strong> - iPad main screen</li>
<li><strong>50x50</strong> - iPad Spotlight</li>
<li><strong>72x72</strong> - iPad main screen</li>
<li><strong>114x114</strong> - iPhone 4 main screen</li>
<li><strong>58x58</strong> - iPhone 4 settings and Spotlight</li>
<li><strong>320x320</strong> - iOS documents</li>
<li><strong>64x64</strong> - iOS documents</li>
</ol>


<p>You may wish to customize your document icons (e.g., by overlaying your icon
on a page icon or somesuch). And of course, iTunes requires that you submit a
512x512 image to be used in the App Store and elsewhere. This is often
customized but will likely be similar in style to your primary app icon.</p>

<p>If you&#8217;re like me, you don&#8217;t have a graphic designer operating at the pixel
level to produce sharp, snazzy icons at all those sizes. So instead of tooling
around in Photoshop every time you tweak your 512x512 master icon (Image ->
Image Size&#8230; -> 57px -> Save As&#8230; -> Undo -> ad infinitum), why not automate
the process?</p>

<p>I&#8217;ve put together a small (tiny) XCode project that uses AppKit to output all
the icon sizes mentioned above. And it&#8217;ll be easy to tweak when the iPad with
Retina Display (<em>fingers crossed</em>) debuts and needs 96px and 144 px versions
of your icon. Throw it into your build system and get freshly-resized icons
every time you compile. Grab it here:</p>

<p><a href="http://www.warrenmoore.net/files/iosicons.zip"><img src="http://www.warrenmoore.net/files/iosicons_dl.png" alt="Click to download" /></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iPhone SDK: Making Your AudioSession Routes Play Nicely with the Vibrate Switch]]></title>
    <link href="http://warrenm.github.com/blog/2010/01/27/making-your-audiosession-routes-play-nicely-with-the-vibrate-switch/"/>
    <updated>2010-01-27T20:07:57-06:00</updated>
    <id>http://warrenm.github.com/blog/2010/01/27/making-your-audiosession-routes-play-nicely-with-the-vibrate-switch</id>
    <content type="html"><![CDATA[<p>So, you&#8217;re writing an awesome multimedia application for the iPhone.
Everything&#8217;s going swimmingly, and you even have some nice animation effects
for when the iPhone is plugged into an external accessory, just like the iPod
app:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">toggleVolumeDisplay:</span><span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="n">show</span> <span class="p">{</span>
</span><span class='line'>  <span class="kt">BOOL</span> <span class="n">isShowing</span> <span class="o">=</span> <span class="p">(</span><span class="n">volumeSlider</span><span class="p">.</span><span class="n">alpha</span> <span class="o">&gt;</span> <span class="mf">0.0</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span> <span class="n">isShowing</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">show</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Animate volume slider down and out, while animating play controls to center of view </span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">isShowing</span> <span class="o">&amp;&amp;</span> <span class="n">show</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Animate volume slider in, while animating play controls up to the top of the view </span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Or something like that. That&#8217;s purely to illustrate what you might be doing in
response to a run-of-the-mill hardware route change (headphones plugged in,
connected to speaker dock, etc.), which of course you&#8217;re detecting like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="c1">// When the view is loaded</span>
</span><span class='line'><span class="n">AudioSessionAddPropertyListener</span><span class="p">(</span> <span class="n">kAudioSessionProperty_AudioRouteChange</span><span class="p">,</span> <span class="n">RouteChangeListener</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">self</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Called later as part of your listener callback </span>
</span><span class='line'><span class="n">CFStringRef</span> <span class="n">state</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'><span class="n">UInt32</span> <span class="n">propertySize</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">CFStringRef</span><span class="p">);</span>
</span><span class='line'><span class="n">OSStatus</span> <span class="n">result</span> <span class="o">=</span> <span class="n">AudioSessionGetProperty</span><span class="p">(</span> <span class="n">kAudioSessionProperty_AudioRoute</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">propertySize</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">state</span> <span class="p">);</span>
</span><span class='line'><span class="k">if</span><span class="p">(</span> <span class="n">result</span> <span class="o">==</span> <span class="n">kAudioSessionNoError</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span> <span class="n">CFStringGetLength</span><span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">([(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="n">state</span> <span class="nl">isEqualToString:</span><span class="s">@&quot;LineOut&quot;</span><span class="p">])</span>
</span><span class='line'>      <span class="c1">// only special case we care about </span>
</span><span class='line'>      <span class="n">shouldShowVolumeControl</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span>
</span><span class='line'>       <span class="p">;</span> <span class="c1">// vibrate switch engaged</span>
</span><span class='line'>  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">result</span> <span class="o">==</span> <span class="n">kAudioSessionUnsupportedPropertyError</span><span class="p">)</span>
</span><span class='line'>      <span class="n">shouldShowVolumeControl</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span> <span class="c1">// probably simulator </span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="p">;</span> <span class="c1">// error encountered </span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This has been documented in <a href="http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Cookbook/Cookbook.html">plenty</a> of <a href="http://stackoverflow.com/questions/833304/how-to-detect-iphone-is-on-silent-mode">places</a>.  Then, you flip the Ring/Vibrate switch and
everything grinds to a halt. Your route change callback doesn&#8217;t get called,
and now your <a href="http://developer.apple.com/library/ios/#documentation/MediaPlayer/Reference/MPVolumeView_Class/Reference/Reference.html">MPVolumeView</a>
declares to the world that the volume isn&#8217;t available. <em>Of course</em> it&#8217;s not
available. That&#8217;s why we&#8217;re going to all this trouble - to <strong>hide the volume
slider when we aren&#8217;t permitted to change it!</strong></p>

<p>After a long time pondering this problem (it&#8217;s been on the backburner for
about a week), I eventually realized that the route change callback might be
dependent on the so-called &#8221;<strong>category</strong>&#8221; of the AudioSession. For example, if
your app just plays alert sounds occasionally, you (probably) don&#8217;t want them
sounding when the phone is set to vibrate. On the other hand, it&#8217;s critical
for audio players like the iPod app to be able to play even when in vibrate
mode. So, how do we go about changing our session category and getting those
mysteriously absent route change callbacks? Like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">UInt32</span> <span class="n">audioCategory</span> <span class="o">=</span> <span class="n">kAudioSessionCategory_MediaPlayback</span><span class="p">;</span>
</span><span class='line'><span class="n">AudioSessionSetProperty</span><span class="p">(</span><span class="n">kAudioSessionProperty_AudioCategory</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">UInt32</span><span class="p">),</span> <span class="o">&amp;</span><span class="n">audioCategory</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>This tells the AudioSession that we want to be regarded as a &#8221;<strong>media
playback</strong>&#8221; app, rather than, for example, an &#8220;ambient sound&#8221; app. Now,
regardless of the position of the vibrate switch, we get notifications when
our iPhone is docked and undocked from external accessories, and we can
animate our volume controls as we desired.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Push]]></title>
    <link href="http://warrenm.github.com/blog/2010/01/26/push/"/>
    <updated>2010-01-26T10:42:38-06:00</updated>
    <id>http://warrenm.github.com/blog/2010/01/26/push</id>
    <content type="html"><![CDATA[<p>For the past year, I&#8217;ve been employed by 352 Media Group, based first in
Gainesville, FL and then in Atlanta, GA.</p>

<p>Recently, I decided that the time had come for me to try to make it as a
freelancer. I&#8217;m not the kind of person who thinks everyone should follow the
path of self-employment. On the other hand, there comes a point in some of our
lives where the idea of working for someone else is so distasteful that the
inevitable pain and isolation that comes from going it alone is actually
attractive.</p>

<p>In other words, it isn&#8217;t all roses. I&#8217;m extremely optimistic about what the
future holds. I know that my skills are valuable once they get in the right
hands. But for the past year, I&#8217;ve had people above and around me figuring out
how to distribute my skills, and now that&#8217;s all on me. Project management, IT,
business development, marketing, public relations, HR&#8230; they all just
collapsed into the singular incomprehensible mass that now rests before me.</p>

<p>Back in August of 2007, I had this to say about my expected trajectory. I&#8217;m
reposting it here, unedited, because I think it&#8217;s important to remember that I
was as clueless then as I feel now, and things have gone pretty well so far.</p>

<p>One of the most striking patterns that has shaped my life is the exponential
feedback of intentionality. What I mean is, I seem to be eerily good at making
things happen that I set my mind to. Before I ever spoke to Microsoft at the
Fall 2006 job fair at UF, I wrote a Post-It note and stuck it to my mirror: &#8220;I
will work for Microsoft.&#8221;</p>

<p>Several months later, I was. Before that, I had opportunities in tech support,
web application development, and game development that were greatly aided by
just thinking hard about what I wanted.</p>

<p>The key to manifesting intentions is to let your subconscious mind discover
opportunities for you, because you could easily burn 25 hours a day looking
actively for them. As long as you keep your goals (which should take no more
than about 20 words to state) in your mind at all times, following your
&#8220;heart&#8221; (really your mind giving you hints about the correct choice of action)
will cause you to converge on your goals.</p>

<p>What happens when you don&#8217;t keep specific goals in mind? You will consistently
converge on whatever occupies your mind for the moment, or on nothing at all.
One way or another, you&#8217;ll notice that you spend a lot of energy just getting
by.</p>

<p>I can&#8217;t conceive how many of my peers accept the reality that shortly (in about
10 months for some of us), they will be sitting at desks in whatever big company
pities them with an entry-level position and 3 days of vacation doing menial
coding tasks that amount to a piss-take in the ocean of personality-free software.</p>

<p>This is not the corporate America of your father. $30 a hour is not enough for
me. $200 an hour isn&#8217;t enough either. Not if I give up control. Not if I&#8217;m
beholden to someone whose seniority will always dictate their position (above
me) in the org chart.</p>

<p>These are the reasons I will not accept a safety net once I graduate. It&#8217;s all
or nothing, because failure is never final. Failure is just one more
motivation to try harder. The alternative to trying again after failure is
death.</p>

<p>So, come what may. King me or kill me.</p>

<p>Truer words. But words without commitment or substance. So, the fresh
realization is that there is no substitute for cutting the cord for real. For
shipping. For taking clients and failing or succeeding on my own merits and
not within someone else&#8217;s support structure. It took awhile to get here, but
here goes&#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Make Terminal Follow Aliases Like Symlinks]]></title>
    <link href="http://warrenm.github.com/blog/2010/01/09/make-terminal-follow-aliases-like-symlinks/"/>
    <updated>2010-01-09T15:34:49-06:00</updated>
    <id>http://warrenm.github.com/blog/2010/01/09/make-terminal-follow-aliases-like-symlinks</id>
    <content type="html"><![CDATA[<p><em>Okay, so you&#8217;re spelunking around in Mac OS using Terminal. You try to &#8216;cd&#8217;
into a directory only to be told that what you&#8217;re trying to get to &#8220;is not a
directory.&#8221; Then you remember that the target directory is actually a shortcut
that you created with Finder. It looks just link a symlink in Finder, so
shouldn&#8217;t it act like one in Terminal?</em></p>

<p>_ _</p>

<p>Unfortunately, in OS X, aliases are treated differently by the command line
than symlinks. In particular, they won&#8217;t be followed by the &#8220;cd&#8221; command,
leading to your present frustration. Fortunately, with a little elbow grease,
you can patch up your shell and be on your merry way.</p>

<p>This is a two-part process requiring a little familiarity with gcc and bash,
but I&#8217;ll try to make it as simple as possible. Firstly, you need this file:
<a href="http://www.macosxhints.com/dlfiles/getTrueName.txt">getTrueName.c</a>. This file
was created by Thos Davis and is licensed under the GPLv2. Save it anywhere,
then compile it with the following command:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gcc -o getTrueName -framework Carbon getTrueName.c</span></code></pre></td></tr></table></div></figure>


<p>This will create the &#8216;getTrueName&#8217; executable in the same directory as the
source. You can add it to your PATH, or just copy it directly to /usr/bin so
it&#8217;s easy to access.</p>

<p>Interestingly, when Terminal opens a new shell, .bashrc is not executed as you
might expect. Instead, under the login shell, .bash_profile is executed. So,
add the following to .bash_profile in your Home directory. You might need to
create it first; it isn&#8217;t there by default.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="k">function </span><span class="nb">cd</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="o">[</span> <span class="k">${#</span><span class="nv">1</span><span class="k">}</span> <span class="o">==</span> 0 <span class="o">]</span>; <span class="k">then </span>
</span><span class='line'><span class="k">    </span><span class="nb">builtin cd </span>
</span><span class='line'><span class="nb">  </span><span class="k">elif</span> <span class="o">[</span> -d <span class="s2">&quot;${1}&quot;</span> <span class="o">]</span>; <span class="k">then </span>
</span><span class='line'><span class="k">    </span><span class="nb">builtin cd</span> <span class="s2">&quot;${1}&quot;</span>
</span><span class='line'>  <span class="k">elif</span> <span class="o">[[</span> -f <span class="s2">&quot;${1}&quot;</span> <span class="o">||</span> -L <span class="s2">&quot;${1}&quot;</span> <span class="o">]]</span>; <span class="k">then </span>
</span><span class='line'><span class="k">    </span><span class="nv">path</span><span class="o">=</span><span class="k">$(</span>getTrueName <span class="s2">&quot;$1&quot;</span><span class="k">)</span>
</span><span class='line'>    <span class="nb">builtin cd</span> <span class="s2">&quot;$path&quot;</span>
</span><span class='line'>  <span class="k">else </span>
</span><span class='line'><span class="k">    </span><span class="nb">builtin cd</span> <span class="s2">&quot;${1}&quot;</span>
</span><span class='line'>  <span class="k">fi</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Effectively, this looks for Finder aliases and resolves them
before deferring to the builtin cd command. Append it to your .bash_profile,
then either execute it or restart Terminal for the changes to take effect. Now
you can cd to Finder aliases within Terminal and have them treated just like
symlinks. Just like it should be.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating Value at Starbucks]]></title>
    <link href="http://warrenm.github.com/blog/2008/10/28/creating-value-at-starbucks/"/>
    <updated>2008-10-28T14:47:05-05:00</updated>
    <id>http://warrenm.github.com/blog/2008/10/28/creating-value-at-starbucks</id>
    <content type="html"><![CDATA[<p>A <a href="http://discussionleader.hbsp.com/davenport/2008/10/is_web_2%0A0_living_on_thin_air.html">recent article</a> by Tom Davenport on the Harvard Business Publishing
metablog has me thinking. Entitled &#8220;Is Web 2.0 Living on Thin Air?,&#8221; the post
asks whether all us hipster Starbucks jet-setting metrosapiens are really
creating value, or just participating in a &#8220;fluffy&#8221; game of social media-
powered self-delusion. I think it&#8217;s the wrong question to ask, but because
Davenport implicitly answers another question, this present post is vindicated
and the fundamental issue at hand is revealed as both beginning and end.
<a href="http://www.imdb.com/name/nm0048127/"></Helmut "The Architect" Bakaitis></a></p>

<p>Concordantly, allow me to ask the question that Davenport really wants to ask:
Regardless of the degree of engagement in often frivolous social networking
activities (i.e., poke wars, media tagging, and adding edges to the social
graph just for the sake of increasing your friend count), who is creating
value and in what is that value based?</p>

<p>Speaking as an aspiring coffee shop hipster creative, I can tell you that when
I&#8217;m sitting down with a Grande Pike Place drip brew, I&#8217;m not going to be
spending much time on facebook; I&#8217;m going to be spending time slicing .PSDs,
writing CSS, and scripting PHP and jQuery, or my language du jour.</p>

<p>I remember reading a much more conservative piece by an individual I could
only imagine being the type of neo-maxi-zoom-dweebie who could make a career
of doling out largely vapid and condescending advice. Substantial Googling and
Snopesing turned up Charles J. Sykes and the relevant quotation: &#8220;Television
is <strong>not</strong> real life. In real life people actually have to leave the coffee
shop and go to jobs.&#8221; <a href="http://www.the50rules.com/Bio/tabid/3402/Default.aspx">Surely enough, he&#8217;s at it again</a>. Suffice to say,
this kind of polemic fails to inspire me. I guess my necktie is a little too
loose for me to get the point.</p>

<p>It turns out that it&#8217;s possible to create value darn-near anywhere these days.
I&#8217;m not saying every job is implicitly mobile; vanishingly few are. But for
those of us knowledge workers who produce the technology that makes everyone
elses&#8217; lives richer and easier, a favorite coffee shop can, as in the vision
for Starbucks envisioned by Howard Shultz, provide a comfortable &#8220;other
place,&#8221; a sacred venue away from the distractions of home where, on the best
days, everything but the workpiece fades into the background and we&#8217;re
cruising along in the zone of maximum productivity.</p>

<p>In short, the value we produce takes the form of applications and systems that
make it easier for people to do whatever it is they do. So indeed, getting
overly engaged in social networking can be a big drain on personal
productivity. But we shouldn&#8217;t confuse such value-sapping minutiae with the
value-creating work of producing sites that encourage engagement, including,
yes, the creation of social media sites.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Blog Action Day 08: Moving Slowly on Poverty]]></title>
    <link href="http://warrenm.github.com/blog/2008/10/16/moving-slowly-on-poverty/"/>
    <updated>2008-10-16T00:38:32-05:00</updated>
    <id>http://warrenm.github.com/blog/2008/10/16/moving-slowly-on-poverty</id>
    <content type="html"><![CDATA[<p>In the last hour or so of the day (on the West Coast, at least), and even
though this site is still under very active construction, I wanted to drop a
quick post for Blog Action Day &#8216;08. The topic of the year is poverty.</p>

<p>As I am a white Anglo-Saxon male who grew up, if not in, at least adjacent to,
the suburbs, most people would assume that my experience with poverty is
minimal. They would be correct. I have never known clawing hunger for days on
end; have never lacked a roof, four walls and a carpeted floor; have never
been the subject of an exposé on wretched conditions in the inner city nor a
child with baleful eyes who could get by with a mere 75 cents a day.</p>

<p>No, being in the first world, I like to imagine that I can get by, due to my
place of privilege in Maslow&#8217;s hierarchy, on just my principles. One of my
friends recently posted on facebook a quotation by Protestant minister William
J. H. Boetcker, from which I take the following excerpts: &#8221;<em>You cannot
strengthen the weak by weakening the strong[&#8230;]</em>&#8221; and &#8221;<em>[__You] cannot help
men permanently by doing for them what they can and should do for
themselves.</em>&#8221; As much as this sentiment reeks of the hackneyed arguments
people make for trickle-down effects between classes, there is something to be
taken from it, and it has everything to do with urgency.</p>

<p>Obviously, the time and money dumped into efforts to &#8220;elevate&#8221; the third world
has benefits, up to and including saving lives that would otherwise be lost.
But is this naive approach adequate when the very lives that are saved lack
the infrastructure, knowledge, and other resources necessary to perpetuate it?
This is what Boetcker meant when he said, &#8220;you cannot help the poor by
destroying the rich.&#8221; If all the wealth generated by the top 3% of earners in
the world went to feed, clothe and shelter children in states of poverty, we
would have not one but two destitute generations as a result.</p>

<p>The good news is that &#8220;elevation&#8221; doesn&#8217;t have to entirely recapitulate the
history of the Western world. We routinely design and commoditize hardware
that is decades ahead of that available in the poorest areas abroad, which
means that the adoption cost in those areas is a tiny fraction of the initial
development cost - yet another instance of the way in which the pricipal of a
personal investment can be multiplied many times over.</p>

<p>So, in moving on poverty, the answer is not strictly an influx of capital.
Obviously large humanitarian organizations must be aware of this at some
level, because their operations are not as naive as the base case described
above. But the broader population should be grounded in firmer realities than
the swollen bellies of starving children half-way around the globe. These
images are tragic and unsettling, and run the risk of inducing despair or a
kind of detached revulsion; instead, where is our collective plan for
introducing infrastructure and slowly burning poverty up in the flames of
progress and accrual of benefits from both social and monetary investments?</p>

<p>It&#8217;s a humanity-sized goal, but for as slow as it would seem to be, it&#8217;s the
fastest way to see the payoff we&#8217;d all love to see.</p>
]]></content>
  </entry>
  
</feed>

