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

  <title><![CDATA[rohan singh]]></title>
  <link href="http://www.rohanradio.com/atom.xml" rel="self"/>
  <link href="http://www.rohanradio.com/"/>
  <updated>2015-06-04T18:01:01-04:00</updated>
  <id>http://www.rohanradio.com/</id>
  <author>
    <name><![CDATA[Rohan Singh]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Favorite Reads — June 2015]]></title>
    <link href="http://www.rohanradio.com/blog/2015/06/04/favorite-reads-june-2015/"/>
    <updated>2015-06-04T17:53:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2015/06/04/favorite-reads-june-2015</id>
    <content type="html"><![CDATA[<p>Here&#8217;s some of my favorite things that I&#8217;ve read lately:</p>

<ul>
<li><p><a href="http://blog.samaltman.com/the-days-are-long-but-the-decades-are-short">The days are long but the decades are short</a>.
A great writeup from Sam Altman with a good smattering of advice on a whole bunch of topics.</p></li>
<li><p><a href="https://medium.com/@leelefever/ready-for-rain-f14703d4f4a8">Ready for Rain: Why Seattleites Crave the End of Summer</a>.
I actually read this over the winter, but it&#8217;s a beautiful article that really made me miss the PNW.</p></li>
<li><p><a href="http://www.lowtechmagazine.com/2011/12/the-chinese-wheelbarrow.html">How to Downsize a Transport Network</a>.
Never in my life did I think that I&#8217;d use the phrase &#8220;gripping, exciting article about wheelbarrows&#8221;,
but that&#8217;s exactly what this is.</p></li>
<li><p><a href="https://www.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/EWD648.html">&#8220;Why is software so expensive?&#8221;</a>.
Something that I thought I already knew the answer to, but which I&#8217;d never thought about like this.</p></li>
</ul>


<p>Discussion welcome.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How Far From Home?]]></title>
    <link href="http://www.rohanradio.com/blog/2012/09/30/how-far-from-home/"/>
    <updated>2012-09-30T22:12:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2012/09/30/how-far-from-home</id>
    <content type="html"><![CDATA[<p>Just like every other Bob Dylan fan in the world, I have been endeavoring to
determine exactly how many roads a man must walk down. To this end, I&#8217;ve been
using passive location tracking for a few years now and have generated a fairly
significant amount of data on my movements and travel. Mostly I&#8217;ve used
<a href="http://latitude.google.com/">Google Latitude</a>, and enabled its optional history
feature.</p>

<p>Many people shudder at the privacy implications of this. Personally, I assume
my cell phone providers have very similar data on hand already, if not with
quite as much accuracy and precision.</p>

<p>I&#8217;ve now started looking through the data to see how my movements have changed
over time. One really stark difference between living in Seattle and living in
Stockholm is my average furthest distance — on any given day how many miles away
from home do I make it?</p>

<p>Check it out. This a map of my movements in Seattle on Thursday, September 29, 2011:</p>

<p><img src="http://www.rohanradio.com/images/blog/roads/seattle-20110929.png"></p>

<p>That was a fairly normal Thursday on which I went downtown for work, went back
home, and then went out for drinks on Capitol Hill. One cool thing about having
this data is that it helps spark your memory — I now remember that exact
evening, who I was with, and some of the conversations that we were having.
Location is an excellent trigger for that sort of thing.</p>

<p>Anyway, you can see that the furthest I made it from home is <strong>4.3 miles</strong>. Most
of my days in Seattle seem to have a furthest distance figure of 4 to 6 miles.</p>

<p>Now, here&#8217;s a map of my movements in Stockholm on this Wednesday, September 26, 2012:</p>

<p><img src="http://www.rohanradio.com/images/blog/roads/stockholm-20120926.png"></p>

<p>Again, a fairly normal Wednesday. I walked to the office, went to a show after
work, and then walked home. The difference, though, is that the furthest I made
it from home is only <strong>0.997 miles</strong>.</p>

<p>One mile instead of five miles. That&#8217;s a pretty significant difference. What
makes it especially interesting for me is that I lived pretty centrally in Seattle
and had a very enviable commute (15 minutes on the bus followed by 5 minutes
on a bike).</p>

<p>The same holds in Stockholm. I live fairly centrally and have a similarly short
commute. But the difference is that in Stockholm a short commute is a 15-minute walk,
rather than a 15-minute bus ride. This is the kind of thing you can enable when
you build for density, and it&#8217;s the kind of thing I hope to see become more
possible in Seattle as well.</p>

<p>Some caveats here:</p>

<ol>
<li><p>Neither of these days were climbing days for me, so I didn&#8217;t make it to the
climbing gym. If I look at climbing days, my distance from home in Seattle is
about 6 miles. In Stockholm it&#8217;s either 2 or 4 miles depending on which gym.
That&#8217;s definitely a less pronounced difference, but I think the theme still
holds.</p></li>
<li><p>Some neighborhoods in Seattle are fairly dense. On my stereotypical lazy Sundays
spent in and around <a href="http://en.wikipedia.org/wiki/Wallingford,_Seattle">Wallingford</a>,
I often didn&#8217;t make it even 2 miles from home. I could walk to restaurants,
the coffee shop, the beer shop and the pub without going even half a mile.
But unlike in Stockholm, that half a mile isn&#8217;t dense enough to have many
offices where a software engineer might be able to find employment. Rather,
I had to go downtown for work.</p></li>
<li><p>While I have a bunch of data points about myself and my movements, this whole
thing is — at its heart — quite anecdotal. I&#8217;m sure there are people
in Seattle who don&#8217;t usually have to go more than a mile from home. And I know
there are people in Stockholm who live further out and have to commute a few
miles.</p></li>
</ol>


<p>Anyway, just some data that I thought was interesting.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Responsive Android Apps with Scala]]></title>
    <link href="http://www.rohanradio.com/blog/2012/05/02/responsive-android-apps-with-scala/"/>
    <updated>2012-05-02T08:40:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2012/05/02/responsive-android-apps-with-scala</id>
    <content type="html"><![CDATA[<p>When it comes to building responsive Android apps, there are two commandments:</p>

<ol>
<li>Don&#8217;t block the UI thread, ever.</li>
<li>Only access and modify the UI from the UI thread itself.</li>
</ol>


<p>The Android Dev Guide goes into <a href="http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html#WorkerThreads">some detail about this</a>.
The usual solutions in Java are to:</p>

<ul>
<li>Spawn a thread that does work and then invoke <a href="http://developer.android.com/reference/android/view/View.html#post%28java.lang.Runnable%29"><code>View.post</code></a>
with a <a href="http://developer.android.com/reference/java/lang/Runnable.html"><code>Runnable</code></a>
that manipulates the UI.</li>
<li>Implement and run an <a href="http://developer.android.com/reference/android/os/AsyncTask.html"><code>AsyncTask</code></a>
that does work in <code>doInBackground</code>, and then manipulates the UI in
<code>onPostExecute</code>.</li>
</ul>


<p>As you can see, both these solutions — though they are the bread and butter of
Android development — are pretty verbose and unwieldy:</p>

<div><script src='https://gist.github.com/2574564.js?file=ThreadWithRunnable.java'></script>
<noscript><pre><code>public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap = loadImageFromNetwork(&quot;http://example.com/image.png&quot;);
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}</code></pre></noscript></div>




<div><script src='https://gist.github.com/2574564.js?file=UsingAsyncTask.java'></script>
<noscript><pre><code>public void onClick(View v) {
    new DownloadImageTask().execute(&quot;http://example.com/image.png&quot;);
}

private class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
    /** The system calls this to perform work in a worker thread and
      * delivers it the parameters given to AsyncTask.execute() */
    protected Bitmap doInBackground(String... urls) {
        return loadImageFromNetwork(urls[0]);
    }
    
    /** The system calls this to perform work in the UI thread and delivers
      * the result from doInBackground() */
    protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }
}</code></pre></noscript></div>


<p>I prefer <code>AsyncTask</code>, which has better semantics, but implementing one
<code>AsyncTask</code> after another quickly becomes tedious. Same with writing line after
line of <code>Runnable</code> boilerplate.</p>

<p>Enter Scala, using either the <a href="https://github.com/jberkel/android-plugin">sbt Android plugin</a>
or <a href="https://github.com/rohansingh/android-scala-test">my Maven-based solution</a>.</p>

<p>The first step is to create an implicit conversion from a function to a <code>Runnable</code>,
which can then be passed to <code>View.post</code> or <code>runOnUiThread</code>. Once we&#8217;ve done
that, it&#8217;s simple to use <code>spawn</code> from <a href="http://www.scala-lang.org/api/current/scala/concurrent/ops$.html"><code>scala.concurrent.ops</code></a>
to do background work.</p>

<p>Here&#8217;s a fully functional example:</p>

<div><script src='https://gist.github.com/2574564.js?file=MainActivity.scala'></script>
<noscript><pre><code>package com.rrsllc.android

import _root_.android.app.Activity
import _root_.android.os.Bundle
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.client.methods.HttpGet
import scala.concurrent.ops._

class MainActivity extends Activity with TypedActivity {
  def textview = findView(TR.textview)

  implicit def toRunnable[F](f: =&gt; F): Runnable =
    new Runnable() { def run() = f }

  override def onCreate(bundle: Bundle) {
    super.onCreate(bundle)
    setContentView(R.layout.main)

    textview.setText(&quot;hello, world!&quot;)

    spawn {
      val client = new DefaultHttpClient()
      val httpGet = new HttpGet(&quot;http://www.android.com&quot;)

      val result = try {
        val response = client.execute(httpGet)
        &quot;The response status was: &quot; + response.getStatusLine.toString
      }
      catch {
        case _ =&gt; &quot;Something went wrong.&quot;
      }

      runOnUiThread { textview.setText(result) }
    }
  }
}</code></pre></noscript></div>


<p>This is so much nicer than the Java alternative. Instead of up to ten lines of boilerplate
for each background task, we end up with just the <code>spawn</code> and <code>runOnUiThread</code>.</p>

<p>If you&#8217;re waiting for that final push to switch over to Scala for your Android development,
I highly recommend the <a href="https://github.com/harrah/xsbt/wiki">sbt</a> plugin for Android. Take
a look at its brilliant <a href="https://github.com/jberkel/android-plugin/wiki/getting-started">Getting Started guide</a>,
which will have you up and running in just a few minutes.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fixing Thunderbolt Ethernet on the MacBook Pro]]></title>
    <link href="http://www.rohanradio.com/blog/2012/02/27/fixing-thunderbolt-ethernet-on-the-macbook-pro/"/>
    <updated>2012-02-27T12:57:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/02/27/fixing-thunderbolt-ethernet-on-the-macbook-pro</id>
    <content type="html"><![CDATA[<p>A few weeks ago, I had to make one of the toughest choices I&#8217;ve had in a while: a 30&#8221; Dell display,
or a 27&#8221; Apple Thunderbolt display. I went with the Thunderbolt display, partly because the colors
are better, but mostly for the convenience of having USB and ethernet integrated into the display.</p>

<p>The way this works, you can just plug your USB peripherals and your network cord into the
Thunderbolt display. Then, whenever you dock your MacBook Pro, you just connect the single
Thunderbolt cable and the display, USB devices, and network all work magically.</p>

<p>It&#8217;s much more convenient than doing the daily morning dance of plugging four or five things into
your MacBook, and it&#8217;s the closest thing we have to a good MacBook Pro dock.</p>

<p>Well, that&#8217;s the theory anyway. In reality, while the USB works fairly decently, the ethernet
connection dropped out on day one, and I haven&#8217;t been able to get it back since. Until today.</p>

<p>Here are the final steps that worked for me. Hopefully somebody else can save a bit of time with
this:</p>

<ol>
<li><p>With the Thunderbolt display connected, visit the Network tab in System Preferences. If you see
<strong>Display Ethernet</strong> and/or <strong>Display FireWire</strong> in the list of network interfaces, select each
one and use the minus (<strong>-</strong>) button at the bottom of the list to remove it.</p>

<p>For me, <strong>Display FireWire</strong> was listed, but <strong>Display Ethernet</strong> was not. I&#8217;ve heard of others
having strange symptoms with neither or both listed.</p></li>
<li><p>Unplug the Thunderbolt display. This will not work if you keep the display plugged in while doing
the next few steps. Trust me, I tried it.</p></li>
<li><p><code>sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist</code></p></li>
<li><p>Restart your MacBook Pro and log back in. Once you&#8217;ve logged in, connect your Thunderbolt display
again.</p></li>
<li><p>Visit the Network tab in System Preferences again. If you see <strong>Display Ethernet</strong> and <strong>Display
FireWire</strong> listed, you&#8217;re all good. Otherwise, click the plus (<strong>+</strong>) button at the bottom of
the list of network interfaces.</p>

<p>From the <strong>Interface</strong> dropdown, select the interface you have missing and click <strong>Create</strong>. If
you have both interfaces missing like I did, you will have to repeat this step for the other
interface.</p></li>
</ol>


<p>After all that, everything seems to be working smoothly for me.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stockholm Speaks Out on ACTA]]></title>
    <link href="http://www.rohanradio.com/blog/2012/02/04/stockholm-speaks-out-on-acta/"/>
    <updated>2012-02-04T13:01:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/02/04/stockholm-speaks-out-on-acta</id>
    <content type="html"><![CDATA[<p>If you haven&#8217;t heard about <a href="http://en.wikipedia.org/wiki/Anti-Counterfeiting_Trade_Agreement">ACTA</a>,
it&#8217;s a damaging piece of legislation very similar to <a href="http://en.wikipedia.org/wiki/Stop_Online_Piracy_Act">SOPA</a>
— the difference being that ACTA is international in scope and much closer to
becoming reality than SOPA ever was. <a href="http://www.youtube.com/watch?v=N8Xg_C2YmG0">Here is a video explaining ACTA</a>
which I found to be quite educational.</p>

<p>Anyway, Stockholm decided to take to the streets to <a href="https://www.facebook.com/events/332489143440319/">protest ACTA today</a>.
Here are a few photos of the fairly well-attended event that I managed to snap
on my phone:</p>

<p><img src="http://www.rohanradio.com/images/blog/stockholm-acta/stockholm-acta-1.jpg"></p>

<p><img src="http://www.rohanradio.com/images/blog/stockholm-acta/stockholm-acta-2.jpg"></p>

<p><img src="http://www.rohanradio.com/images/blog/stockholm-acta/stockholm-acta-3.jpg"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Crazy Color-Coded Problems]]></title>
    <link href="http://www.rohanradio.com/blog/2012/01/29/crazy-color-coded-problems/"/>
    <updated>2012-01-29T12:50:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/01/29/crazy-color-coded-problems</id>
    <content type="html"><![CDATA[<p>Earlier this week I moved from Seattle to Stockholm, where I&#8217;ll be working at
<a href="http://spotify.com/">Spotify</a>. I arrived and started settling in on Friday.
On Saturday, I decided to check out out the local bouldering scene.</p>

<p>There&#8217;s quite a few gyms in the area, and the closest ones to downtown are run
by <a href="http://klattercentret.se">Klättercentret</a> and <a href="http://klatterverket.se">Klätterverket</a>.
The Klättercentret in Solna is the place I was really looking forward to
visiting. But since it&#8217;s closed for renovation until next week, I instead found
myself at the Klättercentret in Telefonplan.</p>

<p>What I found there was a style of setting I had never seen before on such a
scale — instead of being marked by tape, problems are based on holds that
are of the same color and style.</p>

<p>Here&#8217;s a photo of the place by Helena Wahlman at <a href="http://blogs.sweden.se/photo/2010/11/19/climbing-at-klattercentret-telefonplan/">the Swedish photo blog</a>:</p>

<p><a href="http://blogs.sweden.se/photo/2010/11/19/climbing-at-klattercentret-telefonplan/"><img src="http://www.rohanradio.com/images/blog/klattercentret.jpg" title="Bouldering at Klättercentret" ></a></p>

<p>Look closely and you&#8217;ll see that there&#8217;s pretty much no tape on the wall. For
example, neither of the holds the guy in the photo is using are marked. Instead,
he knows to use them because they are yellow.</p>

<p>What little tape there is just marks the start and end of a problem. The color
of the tape is what specifies <a href="http://www.klattercentret.se/svenska/hallen/gradering">the problem&#8217;s approximate grade</a>:</p>

<p><a href="http://www.klattercentret.se/svenska/hallen/gradering"><img src="http://www.rohanradio.com/images/blog/klattercentret-grading.gif"></a></p>

<p>At the moment I&#8217;m not sure if this is a regional thing or just a Klättercentret
thing.</p>

<p>One thing I can tell you is that, at first, I was very, very confused! I&#8217;d
expected a different grading system, but when I first walked up to the wall in
Telefonplan, I seriously had no idea what was going on. Of course, I tried to
figure out what other people were doing, but I&#8217;m not used to looking at the
color of holds.</p>

<p>Until I realized what was up, I just figured everyone was improvising their
own problems. Also, at the time I hadn&#8217;t realized that the vast majority of the
bouldering area at Telefonplan was on a different floor. Those things combined to
make me wonder if I was in some special kind of hell where bouldering was just a
joke.</p>

<p>What finally made it click for me is when I found a long overhanging problem
comprised entirely of bright orange holds. Once I saw that, everything clicked
into place and I could suddenly see all the problems everywhere! There were
quite a few excellent problems, and overall it was a great session.</p>

<p>Thoughts on this style of setting:</p>

<ul>
<li><p><strong>Grading.</strong> The approximate grading is something I can appreciate. It lets
you walk up to a problem and have a general idea of what it&#8217;s going to be
like, but without forming preconceptions of whether or not you can handle it.
Moreover, it reflects the reality of a gym problem where grading is inexact
and approximate, based on the perception of a single setter.</p></li>
<li><p><strong>Visibility.</strong> Once you get used to the idea, identifying holds based on hold
color isn&#8217;t that different from tape color. You do have the same problem as
with tape where similar adjacent colors can be difficult to pick apart. In
some cases, you have an additional problem where heavily-chalked holds become
difficult to identify.</p></li>
<li><p><strong>Style</strong>. Each problem definitely takes on a certain style based on the type
of hold used. I imagine this could be really handy when you want to train a
specific skill. If you pick a problem that starts with a sloper, it&#8217;s going to
be full of slopers that came from the same set. Same with crimps, or jugs or
pockets or what-have-you. As an example, I&#8217;ve set something similar before
using a single set of bright pink crimps, and it was great for training crimps.</p></li>
</ul>


<p>All that said, I&#8217;m still not sure about this system. In a way, I&#8217;m sure it
encourages creativity, as <a href="http://www.huffingtonpost.com/scott-barry-kaufman/does-creativity-require-c_b_948460.html">limits and constraints tend to do</a>.</p>

<p>Yet, the fact remains — with a given set of holds, you can
express more problems and permutations if you can mix holds of different colors.
Then again, the point of setting is to create challenging, climbable problems,
not just to mathematically optimize your theoretical problem space.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Isn't all coding about being too clever?]]></title>
    <link href="http://www.rohanradio.com/blog/2012/01/19/isnt-all-coding-about-being-too-clever/"/>
    <updated>2012-01-19T12:22:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/01/19/isnt-all-coding-about-being-too-clever</id>
    <content type="html"><![CDATA[<p>Every now and then I have a discussion or lecture with my roommate Chris, on some aspect of software
engineer, architecture, process management, or programming in general. His specialization is
psychology, so while this exercise can be cathartic, it&#8217;s largely pointless. I&#8217;ve decided that it
might be more effective to write these things down and post them.</p>

<p>Today, prompted by a discussion on what I should name some new object, Chris asked:</p>

<blockquote><p>Isn&#8217;t all coding about being too clever?</p></blockquote>

<p>I think that is a conception that many laypeople and beginning programmers have — that we should try
to be clever. Seasoned engineers will know that being clever can be one of the worst sins.</p>

<p>Here was my response, paraphrased:</p>

<blockquote><p>The goal is to write the minimal code that (a) gets the job done, (b) doesn&#8217;t break, and (c) is
understandable and maintainable by other people.</p>

<p>&#8220;Clever&#8221; often meets the first requirement, can sometimes meet the second, and always fails
miserably at the third — which is actually the most important one. All things equal, I&#8217;d often
rather have a broken system that I can understand than a rat&#8217;s nest of code that happens to work.</p></blockquote>

<p>That said, sometimes you do come across clever code that meets all of those requirements. These are
small masterpieces and works of art and should be regarded as such.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Extreme Response Times]]></title>
    <link href="http://www.rohanradio.com/blog/2012/01/11/extreme-response-times/"/>
    <updated>2012-01-11T16:01:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/01/11/extreme-response-times</id>
    <content type="html"><![CDATA[<p>Looks like I have some serious optimization to do for the new stuff that I&#8217;ve
been building:</p>

<p><img src="http://www.rohanradio.com/images/blog/extreme-response-times.png"></p>

<p>At least the latency seems pretty good?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Inner-Platform Effect]]></title>
    <link href="http://www.rohanradio.com/blog/2012/01/09/the-inner-platform-effect/"/>
    <updated>2012-01-09T20:45:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2012/01/09/the-inner-platform-effect</id>
    <content type="html"><![CDATA[<p>Today <a href="http://news.ycombinator.com/item?id=3442497">someone on Hacker News</a>
posted a link to the <a href="http://en.wikipedia.org/wiki/Inner-platform_effect">Wikipedia article on the inner-platform effect</a>,
which is &#8220;the tendency of software architects to create a system so customizable as to become a
replica, and often a poor replica, of the software development platform they are using.&#8221;</p>

<p>One of my favorite parts of the article (emphasis mine):</p>

<blockquote><p>In the database world, developers are sometimes tempted to bypass the RDBMS, for
example by storing everything in one big table with two columns labelled key and
value. While this entity-attribute-value model allows the developer to break out
from the structure imposed by an SQL database, it loses out on all the benefits,
since all of the work that could be done efficiently by the RDBMS is forced onto
the application instead. Queries become much more convoluted, the indexes and
query optimizer can no longer work effectively, and data validity constraints
are not enforced. <strong>Such designs rarely make their way into real world production
systems, however, because performance tends to be little better than abysmal,
due to all the extra joins required.</strong></p></blockquote>

<p>Oh man, if only. I can think of at least <a href="http://www.magentocommerce.com/">one example</a> of a
a platform with this very problem — and with the associated horrible performance profile — that is
very widely deployed and used in production environments around the world. I&#8217;m sure you can think of
others.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Actually Dreaming in Code]]></title>
    <link href="http://www.rohanradio.com/blog/2011/12/31/actually-dreaming-in-code/"/>
    <updated>2011-12-31T17:49:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/12/31/actually-dreaming-in-code</id>
    <content type="html"><![CDATA[<p>Before I begin, here are a few great, relevant xkcd&#8217;s:
<a href="http://xkcd.com/719/">#719</a>
<a href="http://xkcd.com/430/">#430</a>
<a href="http://xkcd.com/203/">#203</a></p>

<p>Anyhow, say what you will about Scott Rosenberg&#8217;s book, <em><a href="http://www.amazon.com/gp/product/1400082463?tag=rohanradiocom-20">Dreaming in Code</a></em>
— but the fact is, it makes Googling for experiences of <em>actually dreaming in code</em>
<a href="http://google.com/search?q=dreaming+in+code">fairly impossible</a>.</p>

<p>Personally though, I find dreaming in code to be very real.
My dreams have always quite vividly blended reality and the imaginary, often
leaving me confused as to which is which, and leaving me with a somewhat tenuous
connection to the former. Code dreams are no different, and I&#8217;ve found that mine
fit into three major types:</p>

<ol>
<li><p><strong>The Text Editor</strong>. This is your fairly standard code dream. In my case,
white background, plain text and some code appearing or being written.
Sometimes, it might make sense and actually relate to a project I&#8217;ve been
working on or code I&#8217;ve being writing, but quite often this code doesn&#8217;t make
any sense whatsoever.</p>

<p>Often, there is no background or text, but just the lines and constructs of
code floating in a place where there is no physical reality. I wonder if
mathematicians have dreams similar to these, but with mathematical constructs?</p></li>
<li><p><strong>The Inspiration</strong>. These dreams are comparatively rare, and don&#8217;t actually
seem to involve any coding whatsoever. However, they very specifically relate
to something I am working on, and when I wake up I know how to structure some
code that I have been struggling with.</p>

<p>This seems to be a pretty straightforward case of the brain working on a
waking-world concern while asleep. Too bad the hours aren&#8217;t billable.</p></li>
<li><p><strong>Code Blends With Reality</strong>. This is the strangest type of dream and the
most difficult to relate, but in many ways my favorite. In these dreams,
physical reality seems to blend and mix with the reality of code. While there
is a normal dream of the physical world underlying everything here, in these
dreams I interact with that world with code instead of in the normal physical
manner.</p>

<p>For example, I might find myself writing a script to light a campfire.
Or instead of traveling from place to place by walking or in a car, I might
just fiddle with the parameters that define my location. People may speak in code
or in concepts rather than words.</p></li>
</ol>


<p>Overall, I find #3 to be the most common type of code dream I have, as well as
the most interesting. It lets the world become a playground that is strangely
close to the real world. It is almost as if, in these dreams, magic is real, and
code is magic.</p>

<p>While it&#8217;s probably not the most important thing in the world, I&#8217;m really
curious to hear whether lots of other people out there dream in code, and how
everyone else&#8217;s code dreams differ from mine.</p>

<p>After all, we spend an amazing amount of time asleep throughout the course of
our lives. Who knows, maybe if talk about dreaming code enough, clients will
agree that those hours asleep should be billable after all, eh?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stone Sublimely Self-Righteous]]></title>
    <link href="http://www.rohanradio.com/blog/2011/12/26/stone-sublimely-self-righteous/"/>
    <updated>2011-12-26T19:56:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/12/26/stone-sublimely-self-righteous</id>
    <content type="html"><![CDATA[<p>Every winter for the past few years, I&#8217;ve spent at least a weekend in San Diego.
Not only is the tropical sun a great respite from gloomy Seattle, but San Diego
— against all odds and expectations — is a brilliant beer town, and home to the
iconic <a href="http://www.stonebrew.com">Stone Brewing Co</a>.</p>

<p>To get myself into the right mindset for my upcoming trip, tonight I am
enjoying Stone&#8217;s <em>Sublimely Self-Righteous Ale</em>. As frequent drinkers of Stone
are surely aware, that brewery is full of <a href="http://www.stonebrew.com/arrogantbastard">downright bastards</a>.</p>

<p>Which is why I just had to share this brilliant excerpt from the label on the
back of this dastardly, <a href="http://www.stonebrew.com/sublimely/">self-rightous bottle</a>:</p>

<blockquote><p>Yes, we damn well know our stuff here at Stone, and it would be irresponsible
of us to not acknowledge how remarkable this heavenly creation of ours is. Thus
the name we are compelled to give it — Stone Sublimely Self-Rightous Ale –
serves as a reminder of just how good we are, in both liquid and verbal form.</p></blockquote>

<p>And also:</p>

<blockquote><p>When you&#8217;re good, you&#8217;re good. And when you do something great, the least you
can do is acknowledge it. Others benefit from knowing.</p></blockquote>

<p>For the record, this self-righteous ale lives up to its label and leaves a smile
on your face — or, at least, on mine.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What I've Been Reading (Dec. 26, 2011)]]></title>
    <link href="http://www.rohanradio.com/blog/2011/12/26/what-ive-been-reading-december-26/"/>
    <updated>2011-12-26T14:12:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/12/26/what-ive-been-reading-december-26</id>
    <content type="html"><![CDATA[<p>What follows are the most insightful, interesting, or otherwise
noteworthy articles I&#8217;ve stumbled across over the past couple weeks.</p>

<ul>
<li><p><strong><a href="http://www.readability.com/articles/hvn0le5e">Democracy is not a truth machine</a></strong>.
One of the best articles I&#8217;ve read all week. In it, a bearded philosopher
eloquently demonstrates why democratic processes can&#8217;t be trusted to find
the truth about objective facts about reality. For example, while a democratic
process can be used to decide what we <em>should do</em> about climate change, the
underlying scientific reality is not up for debate.</p></li>
<li><p><strong><a href="http://www.salon.com/2011/12/03/the_evolution_of_monsters/singleton/">Why we invented monsters</a></strong>.
Paul Carr start with the idea that monsters grew into the human
consciousness in the image of predators, such as felines and
snakes. Eventually, as protohumans transformed from a prey species into
predators, our imaginations transformed as well.</p></li>
<li><p><strong><a href="http://www.bbc.co.uk/news/magazine-16037798">The scandal of the Alabama poor cut off from water</a></strong>.
It really kills me that we need a foreign news source to report about the fact
that America&#8217;s infrastructure is failing and the promises of citizenship
aren&#8217;t panning out for some of those who have the greatest need.
Reading this article, others like it, and watching the documentary
<em><a href="http://en.wikipedia.org/wiki/Waiting_for_%22Superman%22">Waiting for &#8220;Superman&#8221;</a></em>
over the weekend has left me with a lot of questions in a place where there
are few good answers.</p></li>
<li><p><strong><a href="http://www.theatlantic.com/international/archive/2011/12/why-americas-death-penalty-just-got-us-sanctioned-by-europe/250324/">Why America&#8217;s Death Penalty Just Got Us Sanctioned by Europe</a></strong>.
The European Union has decided that it will have no part in the barbarism
involved in the methodical killing of human beings by their peers. I
completely agree with Ford Vox&#8217;s characterization of the situation:</p>

<blockquote><p>The death penalty is a blind spot in our democracy, our own peculiar
national <a href="http://en.wikipedia.org/wiki/Anosognosia">anosognosia</a>.
It probably will take the rest of the world shouting
us down in order to recognize our impairment.</p></blockquote></li>
<li><p><strong><a href="http://www.remappingdebate.org/article/tale-two-systems">A tale of two systems</a></strong>.
The folks at <a href="http://www.remappingdebate.org/">Remapping Debate</a> contrast a
failing labor system in America with a robust, unionized system in Germany.</p></li>
<li><p><strong><a href="http://www.samharris.org/blog/item/hitch/">Hitch</a></strong>. Sam Harris, eloquent
as always, on Christopher Hitchens&#8217; death:</p>

<blockquote><p>Needless to say, he was effortlessly lucid and witty—and taking no prisoners.
There should be a name for the peculiar cocktail of emotion I then enjoyed:
one part astonishment, one part relief, two parts envy; stir. It would not be
the last time I drank it in his honor.</p></blockquote></li>
<li><p><strong><a href="http://rrs.co/tlMGyE">Freakonomics: What Went Wrong?</a></strong>. Andrew Gelman and
Kaiser Fung examine many of the conclusions in <em>Freakonomics</em> and
<em>Superfreakonomics</em> which have worked themselves into the cultural
consciousness and which are now taken for granted. Specifically, they show
that many of these conclusions are just plain wrong.</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on Home Walls & Setting]]></title>
    <link href="http://www.rohanradio.com/blog/2011/12/06/thoughts-on-home-walls-setting/"/>
    <updated>2011-12-06T23:40:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/12/06/thoughts-on-home-walls-setting</id>
    <content type="html"><![CDATA[<p>I think of all the things I love about <a href="http://en.wikipedia.org/wiki/Wallingford,_Seattle">where I live</a>,
having a climbing wall in our studio is definitely in my top three. We had a couple
of constraints in constructing the wall:</p>

<ul>
<li>Our lease doesn&#8217;t allow pounding anything into the wall, so the structure had
to be entirely free-standing.</li>
<li>I love bouldering on overhanging walls — the steeper the better. But we wanted
to be sensitive to the fact that overhangs are not everyone&#8217;s cup of tea.</li>
</ul>


<h2>The Wall</h2>

<p>In the end, we settled on an adjustable 10&#8217; x 10&#8217; <a href="http://en.wikipedia.org/wiki/Lean-to">lean-to</a>
design.</p>

<p>My roommate Chris and I have both found that mentioning the dimensions of the wall is a great
heuristic for identifying climbers and non-climbers. The usual response from a
non-climber is along the lines of, &#8220;Really? Isn&#8217;t that too small?&#8221;</p>

<p>Everyone always changes their mind on that after a good workout on the wall.</p>

<p><img src="http://www.rohanradio.com/images/blog/climbing-wall/before.jpg"></p>

<p>Chris and a friend handled most of the construction of the structure, which took
about 40 hours in total. I think the most time-consuming part of the process —
aside from waiting for the deck paint to dry – was drilling each of the dozens upon
dozens of holes and installing a t-nut in each.</p>

<p>As I mentioned earlier, the incline is adjustable. Originally we had a 15°
overhang, but have since dropped the wall down a bit further to 30°. This seems
to be a nice compromise given that our friends are climbers with varying amounts
of experience, specialties, and skill levels.</p>

<h2>Setting — First Try</h2>

<p>Initially, I tried a couple of traditional setting strategies. The specifics
varied, but the basic idea was to visualize the outline of a problem and then
set it piece by piece. I quickly learned a couple of things:</p>

<ol>
<li><p><strong>This takes skill.</strong> Just because you are good at climbing a certain type of
problem does not mean you will be able to set similar satisfying problems.
It&#8217;s a completely different thought process and creative skillset.</p></li>
<li><p><strong>Setting is hard work!</strong> At first I was trying out the problem as I set each
piece, which was very tiring. I heard a better strategy was to set the whole
problem before trying to test and tweak it. This was great advice, but
climbing up and down with holds and screwing them in is still a lot of work.</p></li>
</ol>


<p>I came out with a newfound respect for routesetters at the gyms I
go to, and it gave me some small amount of additional insight into bouldering
problems in general.</p>

<h2>Setting — Second Try</h2>

<p>What ultimately made me try a different strategy was thinking more deeply about
how we were using the wall. Given that the friends I climb with are all at
different levels, we would generally just try climbing around or playing add-on
rather than climbing specific problems.</p>

<p><em>Add-on</em> is a very simple game. In a sense, it&#8217;s the bouldering version of
<a href="http://en.wikipedia.org/wiki/Variations_of_basketball#H-O-R-S-E">H.O.R.S.E</a>.
The first climber chooses a starting position and makes a single move. The next
climber copies that move, and then <em>adds on</em> another move. This is a great game
when you have climbers at different levels, since everyone can play along and
take part in some friendly competition.</p>

<p>Given that we were using the wall this way, I started thinking more about where
to place holds on an individual basis, rather than where to place problems.
Instead of trying to visualize an entire problem, I now just think about where a
single hold might be interesting, and what orientation might make it fun to pull
on.</p>

<p>Since I only have to consider one hold at a time, the cognitive load required is
a lot lower. This is nice, since I&#8217;m not a very good routesetter. By just
throwing up each hold in an interesting position, it&#8217;s a lot easier for me to
fill the whole wall.</p>

<p>Here&#8217;s one of my favorite holds from <a href="http://www.soillholds.com/">So Ill</a>,
brilliantly entitled <em><a href="http://www.soillholds.com/the-picking-jug">The Picking</a></em>:</p>

<p><img src="http://www.rohanradio.com/images/blog/climbing-wall/nose.jpg"></p>

<p>As a field test, we played quite a few games of add-on last Saturday, and it was
tons of fun!</p>

<h2>New Holds &amp; Resetting</h2>

<p>I&#8217;ve subscribed to So Ill&#8217;s <a href="http://www.soillholds.com/sick-kit-club-monthly">hold of the month club</a>,
and it gives me an excuse to reset things and try something new every month or so.
These just arrived recently:</p>

<p><img src="http://www.rohanradio.com/images/blog/climbing-wall/new-holds.jpg"></p>

<p>I took the opportunity to move things around a fair bit. I moved <em>The Picking</em>
much higher up, and rotated it to a fun new orientation. I also threw on a
smattering of underclings and other new stuff.</p>

<p><img src="http://www.rohanradio.com/images/blog/climbing-wall/after.jpg"></p>

<p>I had actually tried putting <em>The Picking</em> in a similar orientation originally,
but found that the it would just spin when pulled sideways — no matter
how tightly I tried to bolt it in. This time I wised up and put a small hold
below it to give it some reinforcement.</p>

<p>New game of add-on tomorrow, and we&#8217;ll see how it goes!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Installing pgmagick on OS X]]></title>
    <link href="http://www.rohanradio.com/blog/2011/12/02/installing-pgmagick-on-os-x/"/>
    <updated>2011-12-02T08:18:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/12/02/installing-pgmagick-on-os-x</id>
    <content type="html"><![CDATA[<p><a href="http://pypi.python.org/pypi/pgmagick/">pgmagick</a> is a Python wrapper for
for <a href="http://imagemagick.org/">ImageMagick</a> (or
<a href="http://graphicsmagick.org/">GraphicsMagick</a>). I needed it for something I was
trying to run yesterday, but the instructions for OS X seem to have gotten lost
in the depths of the Internet.</p>

<p>I&#8217;m assuming you have a working <a href="http://mxcl.github.com/homebrew/">Homebrew</a>,
Python, and <a href="http://pypi.python.org/pypi/pip"><code>pip</code></a>. You&#8217;ll also need
<a href="https://gist.github.com/2427291">my Homebrew formula for Boost</a>.</p>

<p>Once you&#8217;ve got that, it&#8217;s pretty straightforward:</p>

<pre><code>$ brew install imagemagick --with-magick-plus-plus
$ brew install boost --with-thread-unsafe
$ pip install pgmagick
</code></pre>

<p>Building Boost takes a long time so don&#8217;t fret if you don&#8217;t see anything for a
while. Try it out and it should work:</p>

<pre><code>$ python
Python 2.7.2 (default, Oct 20 2011, 17:33:50) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import pgmagick
&gt;&gt;&gt; pgmagick.gminfo.library + ' ' + pgmagick.gminfo.version
'ImageMagick 6.x.x'
</code></pre>

<p>For extra credit, you should also be able to install the
<a href="http://www.pythonware.com/products/pil/">Python Imaging Library (PIL)</a>
as well:</p>

<pre><code>$ pip install -f http://effbot.org/downloads Imaging==1.1.7
</code></pre>

<p>This all worked for me on OS X 10.7 (Lion). Your mileage may vary on other
versions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Optimism]]></title>
    <link href="http://www.rohanradio.com/blog/2011/07/25/optimism/"/>
    <updated>2011-07-25T17:03:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2011/07/25/optimism</id>
    <content type="html"><![CDATA[<p>Software engineers are some of the most optimistic people I know.</p>

<p>Case in point:</p>

<p><img src="http://www.rohanradio.com/images/blog/clint-optimism.png"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Don't Break the Back Button]]></title>
    <link href="http://www.rohanradio.com/blog/2011/06/24/dont-break-the-back-button/"/>
    <updated>2011-06-24T21:42:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2011/06/24/dont-break-the-back-button</id>
    <content type="html"><![CDATA[<p>Recently, I&#8217;ve worked on/with or used a few Android applications that &#8220;disable&#8221;
the back button in some cases.</p>

<p>If you haven&#8217;t used Android, the back button is a prominent feature. Nearly
every Android device has a hardware back button. The system maintains a stack of
all the activities the user has navigated to, and when the user presses the back
button, <a href="http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html#taking_over_back_key">it takes the user to the previous activity</a>.</p>

<p>This works both inside individual apps and also across process boundaries. For
example, when I&#8217;m reading an email and push the back button, I end up back at my
inbox. If I push the back button again, I&#8217;ll end up at whatever app I was in
before I opened Gmail.</p>

<p>This functionality is all provided by the OS, so all you have to do to get it
right is to not break anything.</p>

<p>Nonetheless, many developers have taken it upon themselves to intercept the back
button and swallow it. Here&#8217;s what this is like when you intercept the back
button on the web:</p>

<p><img src="http://www.rohanradio.com/images/blog/broken-back-button.png"></p>

<p>In other words, it&#8217;s completely obnoxious and unacceptable. Unfortunately, it
seems that which we know to be obviously true in web development, is quickly
forgotten when it comes to a mobile device.</p>

<p>I remember reading about
<a href="http://www.mendeley.com/research/portable-eyetracking-a-study-of-natural-eye-movements/">a study at the Rochester Institute of
Technology</a>
a few years ago, wherein researchers mounted eye-tracking devices on subjects
who were washing their hands. A very simple task: washing your hands.</p>

<p>What the study found was a new type of eye movement, the &#8220;planful&#8221; movement. In
short, before interacting with any object, we build a model of that interaction
in our minds and look at the object, without being consciously aware that we are
doing so. For example, your eyes and your brain are glancing at and scouting out
the paper towel dispenser while you are still rinsing your hands.</p>

<p>The same concept that applies to navigating your bathroom sink applies to
navigating a mobile operating system. Your app may only be displaying one
specific activity on the screen, but you can be sure that the user has
constructed a mental model of how they are going to navigate through your app,
through their device, to accomplish whatever they need to accomplish today.</p>

<p>Most of the time, these mental models aren&#8217;t fully conscious or completely
articulated. Ask someone how they would get from Angry Birds to Gmail, and
you&#8217;ll hear something along the lines of, &#8220;I&#8217;ll save and back out of the game
and then open up Gmail.&#8221; Their mental machinery has abstracted away the minutiae
of what they would specifically push or click on.</p>

<p>Instead, users just rely on their intuitive experience of how to navigate a
system. That intuitive experience makes certain assumptions regarding how this
virtual world is structured. These assumptions are often as strong as your
assumptions regarding the physical world — up is up, down is down, and if you
retrace the way you came, you&#8217;ll always end up where you started.</p>

<p>When you break these unconscious and conscious assumptions regarding how things
work, you are basically giving your users a <a href="http://xkcd.com/371/">mental segfault</a>:</p>

<p><img src="http://imgs.xkcd.com/comics/compiler_complaint.png" title="'XKCD comic #371'" ></p>

<p>Don&#8217;t break the back button.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting ASP.NET to play nice with Opera &amp; wget]]></title>
    <link href="http://www.rohanradio.com/blog/2011/03/28/getting-asp-dot-net-to-play-nice-with-opera-and-wget/"/>
    <updated>2011-03-28T15:43:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2011/03/28/getting-asp-dot-net-to-play-nice-with-opera-and-wget</id>
    <content type="html"><![CDATA[<p>A few weeks ago we noticed an issue with some crawlers and search engines being
unable to crawl <a href="http://www.starbucks.com">Starbucks.com</a>. Around the same time,
<a href="http://my.opera.com/karlcow/">Karl Dubost</a> from Opera discovered that
<a href="http://my.opera.com/karlcow/blog/2011/03/03/wrong-to-be-right-with-xhtml">visitors using Opera were getting a parse error</a>.
In fact, a number of high-profile ASP.NET sites seem to be impacted by the latter issue.</p>

<p>If you&#8217;re just looking for the quick fix, skip ahead to the bottom of this post.</p>

<p>To sum up the issue, our server was responding with a <code>Content-Type</code> header of
<code>application/xhtml+xml</code> to both Opera and <code>wget</code>. In Opera, this triggers an XML
parser, which would fail since our content is actually <code>text/html</code>.</p>

<p>Of course, nowhere in our code were explicitly setting the <code>Content-Type</code> header
to anything other than <code>text/html</code>, so the behavior was puzzling. Additionally,
the server was responding with an <code>application/xhtml+xml</code> type even when the
Accept header from the browser specified <code>*/*</code>. This made no sense at all, since
if the browser was willing to accept anything, we should be sending the content
in its default <code>text/html</code>.</p>

<h2>ASP.NET Browser Detection</h2>

<p>As it turns out, ASP.NET has a somewhat questionable
<a href="http://msdn.microsoft.com/en-us/library/3yekbd5b.aspx">feature that allows you detect browser types and capabilities</a>,
largely based on the browser&#8217;s request headers. This is mediated through a
<a href="http://msdn.microsoft.com/en-us/library/ms228122.aspx">browser definition file</a>
(*.browser), which is just a bunch of XML that matches up request header
patterns to browser types and know capabilities. This file lives in your
ASP.NET applicaiton&#8217;s App_Browsers folder.</p>

<p>The known capabilities for the current user agent are all available through the
<code>HttpContext.Request.Browser</code> object.</p>

<p>As I said, all very questionable. The idea of having a giant database of
browsers and what they are like just rubs me wrong and strikes me as
unmaintainable. In fact, we only tried out the whole browser definition file as
part of a proof-of-concept for some mobile pages. The feature never quite worked
correctly, so we abandoned it and thought that was the end of that.</p>

<h2>The insidious preferredRenderingMime</h2>

<p>Of course, that wasn&#8217;t the end of that. For each browser definition in a browser
definition file, you can define a <code>preferredRenderingMime</code> value for a browser.
For example:</p>

<pre><code>&lt;capabilities&gt;
  &lt;capability name="preferredRenderingMime" value="application/xhtml+xml" /&gt;
&lt;/capabilities&gt;
</code></pre>

<p>Most of the larger *.browser file compilations floating around the Web have
Opera set to preferring a MIME type of <code>application/xhtml+xml</code>. A lot of files
will default to a preferred type of <code>application/xhtml+xml</code> for all browsers that
pass an Accept: <em>/</em> request header.</p>

<p>And even though we use ASP.NET MVC and no longer are using any of the browser
detection stuff at all, the System.Web.UI.Page class has this fun code that runs
when the page is processed:</p>

<figure class='code'> <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='csharp'><span class='line'><span class="k">private</span> <span class="k">void</span> <span class="nf">SetIntrinsics</span><span class="p">(</span><span class="n">HttpContext</span> <span class="n">context</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">allowAsync</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">HttpCapabilitiesBase</span> <span class="n">browser</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">_request</span><span class="p">.</span><span class="n">Browser</span><span class="p">;</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="n">_response</span><span class="p">.</span><span class="n">ContentType</span> <span class="p">=</span> <span class="n">browser</span><span class="p">.</span><span class="n">PreferredRenderingMime</span><span class="p">;</span>
</span><span class='line'>
</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>Brilliant, right? Since Opera prefers XHTML, this code does you the favor of
automatically setting your response content type to <code>application/xhtml+xml</code>. Of
course, since your actual content is still HTML, this causes an XML parse error
and all your Opera visitors are hosed.</p>

<p>This might make sense if you are doing the classic ASP.NET Web Forms thing with
server controls that adapt their rendering based on the browser&#8217;s preferred
MIME. But even if you are using ASP.NET MVC, your .aspx views are still
essentially pages, and this old code will still run.</p>

<h2>Broken <code>wget</code></h2>

<p>Unfortunately, this <code>SetIntrinsics</code> code has another nasty side effect. If your
application has already sent out response headers or content, it will just throw
an exception since <code>Response.ContentType</code> can&#8217;t be set after response headers have
already been sent.</p>

<p>In the case of Starbucks.com, this meant that issue wasn&#8217;t just that Opera
visitors experienced a parse error, but that an exception would be thrown for
any browser for which ASP.NET tried to switch the <code>Response.ContentType</code>. This
would result in absolutely no content being served, resulting in a blank page
for Opera visitors.</p>

<p>Furthermore, a large percentage of crawlers and search engines use <code>wget</code> to
grab pages. <code>wget</code> sends an <code>Accept</code> header of <code>*/*</code>, and runs into the same
no-content issue. A fine mess all around.</p>

<h2>The fix</h2>

<p>The simplest fix, of course, is to get rid of any *.browser files you may be
using in your application. I understand redirecting to a mobile version of your
site for mobile browsers or the like, but basing any major functionality on
guesses about the user&#8217;s browser is a great path to future pain.</p>

<p>If, however, you want to keep your browser definition files around, consider
removing any uses of the <code>preferrendRenderingMime</code> capability. Here&#8217;s a regex that
should be able to find those instances for you:</p>

<pre><code>^.+"preferredRenderingMime".+$
</code></pre>

<p>Just do a find &amp; replace on that and you should be good to go. This is what we
ended up doing for <a href="http://www.starbucks.com">Starbucks.com</a> and
<a href="http://starbucks.co.uk">Starbucks.co.uk</a>, which I&#8217;m happy to say now
work perfectly for Opera and <code>wget</code> users alike!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I don't even know where to start with this torta.]]></title>
    <link href="http://www.rohanradio.com/blog/2011/03/24/i-dont-even-know-where-to-start-with-this-torta/"/>
    <updated>2011-03-24T12:37:00-04:00</updated>
    <id>http://www.rohanradio.com/blog/2011/03/24/i-dont-even-know-where-to-start-with-this-torta</id>
    <content type="html"><![CDATA[<p><img src="http://www.rohanradio.com/images/blog/torta.jpg"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Outlier is pretty awesome]]></title>
    <link href="http://www.rohanradio.com/blog/2011/03/02/outlier-is-pretty-awesome/"/>
    <updated>2011-03-02T10:36:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/03/02/outlier-is-pretty-awesome</id>
    <content type="html"><![CDATA[<blockquote><p>We love our bikes not because we race them, ride trails or perform tricks with them, although sometimes we do all of that. We love our bikes mainly because they are our transportation, our freedom, our way of moving through the spaces we call our home.</p><footer><strong>Outlier</strong> <cite><a href='http://outlier.cc'>outlier.cc/&hellip;</a></cite></footer></blockquote>


<p><img src="http://www.rohanradio.com/images/blog/outlier.png"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Posting JSON with jQuery]]></title>
    <link href="http://www.rohanradio.com/blog/2011/02/22/posting-json-with-jquery/"/>
    <updated>2011-02-22T22:23:00-05:00</updated>
    <id>http://www.rohanradio.com/blog/2011/02/22/posting-json-with-jquery</id>
    <content type="html"><![CDATA[<p>Lately, I&#8217;ve been a big fan of JSON via HTTP POST to send data to a Web service.
It&#8217;s awesome for a bunch of reasons:</p>

<ul>
<li><p><strong>Works equally well for simple and complex data.</strong> Regular HTTP POST works great
for simple data, but gets unwieldy for anything hierarchical. XML works for
complex data, but is too wordy for something simple.</p></li>
<li><p><strong>Compact and human-readable.</strong> Really, this just comes with the territory when
you&#8217;re using JSON for anything.</p></li>
<li><p><strong>Easy to debug using Fiddler or related tools.</strong> You just have to type in or
modify a JSON string when you want to do some ad-hoc testing.</p></li>
<li><p><strong>Easy to add support for to any server.</strong> In fact, support for receiving JSON
POST is built into the latest versions of
<a href="http://docs.cherrypy.org/dev/refman/lib/jsontools.html">CherryPy</a> and
<a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.jsonvalueproviderfactory.aspx">ASP.NET MVC</a>.</p></li>
</ul>


<p>That said, JSON POST still doesn&#8217;t seem to be all that popular compared to
an old-style URL-encoded HTTP POST. One explanation I&#8217;ve heard proposed for
this is the lack of support in jQuery. By default, jQuery goes with the
old-style POST. You know:</p>

<pre><code>foo=bar&amp;abc=xyz&amp;x=123
</code></pre>

<p>Sure, you can pass in a complex type and jQuery will gladly serialize it
into this format for you, but good luck trying to read that with your human
eyes, or trying to piece it back together on the server in any sane way.</p>

<p>The really sad thing is that jQuery has a great <code>getJSON()</code> function that lets
you receive JSON output and parses it appropriately. But there is no
built-in support for posting raw JSON.</p>

<p>To that end, I threw together this little plugin that I use all over the
place:</p>

<figure class='code'> <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='js'><span class='line'>  <span class="nx">jQuery</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">postJSON</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">data</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
</span><span class='line'>        <span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;POST&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">url</span><span class="o">:</span> <span class="nx">url</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">data</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">data</span><span class="p">),</span>
</span><span class='line'>        <span class="nx">success</span><span class="o">:</span> <span class="nx">callback</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">dataType</span><span class="o">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">contentType</span><span class="o">:</span> <span class="s2">&quot;application/json&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">processData</span><span class="o">:</span> <span class="kc">false</span>
</span><span class='line'>      <span class="p">});</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>



]]></content>
  </entry>
  
</feed>
