<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Mark Hansen</title>
 
 <link href="http://www.markhansen.co.nz/" />
 <updated>2013-05-08T10:57:55+10:00</updated>
 <id>http://www.markhansen.co.nz/</id>
 <author>
   <name>Mark Hansen</name>
   <email>mark@markhansen.co.nz</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mhansen" /><feedburner:info uri="mhansen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry>
   <title>Visualising NZ's Stolen Cars, Part 2</title>
   <link href="http://www.markhansen.co.nz/stolen-vehicles-pt2/" />
   <updated>2011-12-21T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/stolen-vehicles-pt2</id>
   <content type="html">&lt;p&gt;I had a lot of fun making this visualization. &lt;a href='https://mbostock.github.com/d3/'&gt;d3.js&lt;/a&gt; + &lt;a href='https://documentcloud.github.com/backbone/'&gt;Backbone.js&lt;/a&gt; + &lt;a href='https://jashkenas.github.com/coffee-script/'&gt;CoffeeScript&lt;/a&gt; is an amazing combination.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s all totally standards-compliant HTML5. Boxes are drawn with inline SVG, &lt;del&gt;and transitions are run in CSS for hardware acceleration&lt;/del&gt; (edit: they aren&amp;#8217;t by default, you have to do a little extra work for that, see comments). Popovers are &lt;a href='https://twitter.github.com/bootstrap/'&gt;Twitter Bootstrap&lt;/a&gt;.&lt;/p&gt;
&lt;div id='stolenvehiclespt2'&gt;
  &lt;h3&gt;Choose a Region&lt;/h3&gt;
  &lt;div id='regionChooser'&gt; &lt;/div&gt;
  &lt;h3 id='regionTitle'&gt; &lt;/h3&gt;
  &lt;div&gt;
    &lt;svg id='weekGraph'&gt; &lt;/svg&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;svg id='daysGraph'&gt; &lt;/svg&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s crazy how much the number of stolen cars has picked up in the last few days approaching Christmas.&lt;/p&gt;

&lt;h3 id='a_code_walkthrough'&gt;A Code Walkthrough&lt;/h3&gt;

&lt;p&gt;As an example of how to do these things with coffeescript, d3, and backbone, here&amp;#8217;s the code used to generate the weekDays graph, showing the number of stolen vehicles per weekday.&lt;/p&gt;

&lt;h4 id='the_backbone_bits'&gt;The Backbone Bits&lt;/h4&gt;

&lt;p&gt;The whole widget is in one javascript class that takes care of itself - WeekGraph. It extends from Backbone.View, and its constructor hooks it up with an HTML element - &lt;code&gt;@el&lt;/code&gt;, and a data model - &lt;code&gt;@model&lt;/code&gt;. The view then listens for &amp;#8216;change&amp;#8217; events coming off the model, and rerenders whenever the model changes. In this way, the view and model stay in sync.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nv'&gt;WeekGraph = &lt;/span&gt;&lt;span class='nx'&gt;Backbone&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;View&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;
  &lt;span class='nv'&gt;height: &lt;/span&gt;&lt;span class='mi'&gt;150&lt;/span&gt;
  &lt;span class='nv'&gt;width: &lt;/span&gt;&lt;span class='mi'&gt;420&lt;/span&gt;
  &lt;span class='nv'&gt;initialize: &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class='nx'&gt;@model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;bind&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;change&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@render&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That was the wiring (decoupling and dependency injection if you&amp;#8217;re into that).&lt;/p&gt;

&lt;h4 id='the_d3_bits'&gt;The d3 Bits&lt;/h4&gt;

&lt;p&gt;The render() method is where the real magic happens, rendering that data model into the HTML element, so we can see it on screen.&lt;/p&gt;

&lt;p&gt;First, separate the stolen vehicles data by weekday. This is accomplished with d3.nest().&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;  &lt;span class='nv'&gt;render: &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class='nv'&gt;weekDays = &lt;/span&gt;&lt;span class='nx'&gt;d3&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;nest&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;(d) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;dayOfWeek&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;entries&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;@model&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;selectedVehicles&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We need to separate the weekdays on the graph horizontally across the x axis.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;x&lt;/code&gt; is a function that does this. You could just use a linear function, but d3 has scale function helpers to make changing the domain and range of these functions really easy, without having to manipulate equations when you want to change the width.&lt;/p&gt;

&lt;h4 id='the_d3_scales'&gt;The d3 Scales&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nv'&gt;x = &lt;/span&gt;&lt;span class='nx'&gt;d3&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;linear&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;domain&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='c1'&gt;# weekdays&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;range&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;6&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;cellPadding&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;cellSize&lt;/span&gt;&lt;span class='p'&gt;)])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Also, the bars need to have a height, decided by the number of vehicles stolen that day. &lt;code&gt;y&lt;/code&gt; is a linear scale that turns vehicles stolen into a pixel height for the bar.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m also making the bar darker when there&amp;#8217;s more vehicles stolen that day. d3 can also make scales that interpolate between colors. This seemed a bit magic to me, but really d3 just has a list of color strings, and turns them into RGB colors and interpolates them.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nv'&gt;maxWeekday = &lt;/span&gt;&lt;span class='nx'&gt;_&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;max&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;weekDays&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='nv'&gt;maxPerWeek = &lt;/span&gt;&lt;span class='nx'&gt;maxWeekday&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;

&lt;span class='nv'&gt;height = &lt;/span&gt;&lt;span class='nx'&gt;d3&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;linear&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;domain&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;maxPerWeek&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;range&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;@height&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;

&lt;span class='nv'&gt;color = &lt;/span&gt;&lt;span class='nx'&gt;d3&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;scale&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;linear&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;domain&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;maxPerWeek&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;range&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;white&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;darkblue&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='the_d3_datadom_join'&gt;The d3 Data-DOM Join&lt;/h4&gt;

&lt;p&gt;Now let&amp;#8217;s select the SVG element, set the width and height, and do a relational join between our weekDay data and the bar DOM elements. I&amp;#8217;ll explain in a second.&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nv'&gt;bars = &lt;/span&gt;&lt;span class='nx'&gt;d3&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;select&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;@el&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;@width&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;@height&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;selectAll&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;rect.weekDay&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;weekDays&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;data()&lt;/code&gt; relational join operator gives us three selections:&lt;/p&gt;

&lt;h4 id='the_updating_elements'&gt;The Updating Elements&lt;/h4&gt;

&lt;p&gt;1: &lt;code&gt;update&lt;/code&gt;. data that already existed in the DOM, but might have changed.&lt;/p&gt;

&lt;p&gt;So we update the DOM. Use a nice transition of 1000ms. We can pass functions that have &lt;code&gt;(d, i)&lt;/code&gt; arguments. &lt;code&gt;d&lt;/code&gt; is the data associated with that DOM element, &lt;code&gt;i&lt;/code&gt; is the data index. Transitions are all interpolated nicely.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nx'&gt;bars&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;transition&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;duration&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1000&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d, i) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@height&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='nx'&gt;height&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d, i) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;height&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;fill&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;color&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='the_new_elements'&gt;The New Elements&lt;/h4&gt;

&lt;p&gt;2: &lt;code&gt;enter()&lt;/code&gt;. Like an actor entering the stage. Data that doesn&amp;#8217;t have a DOM element yet. So we append elements to the DOM for each new datum, and set the location, size, class, and fill according to the data values.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nx'&gt;bars&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;enter&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;svg:rect&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d, i) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@height&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='nx'&gt;height&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;height&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d, i) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;height&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;cellSize&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;class&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;weekDay&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;fill&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nf'&gt;(d) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;color&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;d&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='the_exiting_elements'&gt;The Exiting Elements&lt;/h4&gt;

&lt;p&gt;3: &lt;code&gt;exit()&lt;/code&gt;. Like an actor exiting the stage. Elements that don&amp;#8217;t match up with any data we have. The elements used to match up with some data, but they don&amp;#8217;t any more. So we remove the elements from the DOM.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;&lt;span class='nx'&gt;bars&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;exit&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;remove&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='the_popovers'&gt;The Popovers&lt;/h4&gt;

&lt;p&gt;Finally, I hooked up a twipsy overlay on mouseover. This uses twitter bootstrap&amp;#8217;s twipsy plugin. It demonstrates how each DOM element contains a property &lt;code&gt;__data__&lt;/code&gt; that contains the d3 data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@$&lt;/code&gt; is &lt;code&gt;this.$&lt;/code&gt;, a jQuery selector scoped to the local backbone element. It&amp;#8217;s handy to make sure one view doesn&amp;#8217;t accidentally attach handlers to another view&amp;#8217;s elements.&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;@$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;rect.weekDay&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;twipsy&lt;/span&gt;
      &lt;span class='nv'&gt;title: &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class='nx'&gt;weekDayName&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;@__data__&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;].&lt;/span&gt;&lt;span class='nx'&gt;date&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;
        &lt;span class='nx'&gt;@__data__&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;values&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; Reports&amp;quot;&lt;/span&gt;
      &lt;span class='nv'&gt;html: &lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;
      &lt;span class='nv'&gt;placement: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;above&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;I hope this has given you a taste of how general and powerful &lt;a href='https://mbostock.github.com/d3/'&gt;d3&lt;/a&gt; is. It&amp;#8217;s a really enjoyable library to use, and it combines well with &lt;a href='https://documentcloud.github.com/backbone/'&gt;Backbone&lt;/a&gt; and &lt;a href='https://jashkenas.github.com/coffee-script/'&gt;CoffeeScript&lt;/a&gt;. Highly recommended.&lt;/p&gt;
&lt;style&gt;
    #stolenvehiclespt2 .highlight {
      stroke: blue;
    }
    #stolenvehiclespt2 label {
      display: inline-block;
    }
    .carBox {
        width: 7px;
        height: 12px;
        display: inline-block;
        border: 1px solid black;
        line-height: 6px;
        margin: 1px;
    }
    #stolenvehiclespt2 .regionBox {
      height: 1em;
      display: inline-block;
    }
    /* nicked from bootstrap */
    .twipsy {
      display: block;
      position: absolute;
      visibility: visible;
      padding: 5px;
      font-size: 15px;
      z-index: 1000;
      filter: alpha(opacity=80);
      -khtml-opacity: 0.8;
      -moz-opacity: 0.8;
      opacity: 0.8;
    }
    .twipsy.above .twipsy-arrow {
      bottom: 0;
      left: 50%;
      margin-left: -5px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-top: 5px solid #000000;
    }
    .twipsy.left .twipsy-arrow {
      top: 50%;
      right: 0;
      margin-top: -5px;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-left: 5px solid #000000;
    }
    .twipsy.below .twipsy-arrow {
      top: 0;
      left: 50%;
      margin-left: -5px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-bottom: 5px solid #000000;
    }
    .twipsy.right .twipsy-arrow {
      top: 50%;
      left: 0;
      margin-top: -5px;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-right: 5px solid #000000;
    }
    .twipsy-inner {
      padding: 3px 8px;
      background-color: #000000;
      color: white;
      text-align: center;
      max-width: 200px;
      text-decoration: none;
      -webkit-border-radius: 4px;
      -moz-border-radius: 4px;
      border-radius: 4px;
    }
    .twipsy-arrow {
      position: absolute;
      width: 0;
      height: 0;
    }
    .popover {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 1000;
      padding: 5px;
      display: none;
    }
    .popover.above .arrow {
      bottom: 0;
      left: 50%;
      margin-left: -5px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-top: 5px solid #000000;
    }
    .popover.right .arrow {
      top: 50%;
      left: 0;
      margin-top: -5px;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-right: 5px solid #000000;
    }
    .popover.below .arrow {
      top: 0;
      left: 50%;
      margin-left: -5px;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      border-bottom: 5px solid #000000;
    }
    .popover.left .arrow {
      top: 50%;
      right: 0;
      margin-top: -5px;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-left: 5px solid #000000;
    }
    .popover .arrow {
      position: absolute;
      width: 0;
      height: 0;
    }
    .popover .inner {
      background: #000000;
      background: rgba(0, 0, 0, 0.8);
      padding: 3px;
      overflow: hidden;
      width: 280px;
      -webkit-border-radius: 6px;
      -moz-border-radius: 6px;
      border-radius: 6px;
      -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
      -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
      box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
    }
    .popover .title {
      background-color: #f5f5f5;
      padding: 9px 15px;
      line-height: 1;
      -webkit-border-radius: 3px 3px 0 0;
      -moz-border-radius: 3px 3px 0 0;
      border-radius: 3px 3px 0 0;
      border-bottom: 1px solid #eee;
    }
    .popover .content {
      background-color: #ffffff;
      padding: 14px;
      -webkit-border-radius: 0 0 3px 3px;
      -moz-border-radius: 0 0 3px 3px;
      border-radius: 0 0 3px 3px;
      -webkit-background-clip: padding-box;
      -moz-background-clip: padding-box;
      background-clip: padding-box;
    }
    .popover .content p, .popover .content ul, .popover .content ol {
      margin-bottom: 0;
    }
    .fade {
      -webkit-transition: opacity 0.15s linear;
      -moz-transition: opacity 0.15s linear;
      -ms-transition: opacity 0.15s linear;
      -o-transition: opacity 0.15s linear;
      transition: opacity 0.15s linear;
      opacity: 0;
    }
    .fade.in {
      opacity: 1;
    }
&lt;/style&gt;&lt;script src='/assets/javascripts/jquery-1.7.min.js'&gt; &lt;/script&gt;&lt;script src='/stolen-vehicles-pt2/all.js'&gt; &lt;/script&gt;</content>
 </entry>
 
 <entry>
   <title>Visualising New Zealand's Stolen Vehicle Database</title>
   <link href="http://www.markhansen.co.nz/stolen-vehicles-pt1/" />
   <updated>2011-12-10T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/stolen-vehicles-pt1</id>
   <content type="html">&lt;div id='mostCommonStolenMakes' style='height:600px; overflow-y:scroll;'&gt;
&lt;h4&gt;Stolen Vehicles, by Make&lt;/h4&gt;
&lt;/div&gt;
&lt;p&gt;Mouseover the bars for a visualisation of the colors of the stolen cars.&lt;/p&gt;

&lt;h3 id='the_database'&gt;The Database&lt;/h3&gt;

&lt;p&gt;A few days ago, the NZ Police &lt;a href='http://www.police.govt.nz/news/release/30151.html'&gt;launched&lt;/a&gt; a &lt;a href='http://www.police.govt.nz/stolen/vehicles'&gt;public database of stolen cars&lt;/a&gt;. It&amp;#8217;s a snapshot taken from the Police Vehicle of Interest database, updated 3x daily.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"It will be a resource for security guards, insurance companies, moteliers,
scrap metal dealers and community policing patrols."&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;"It also has obvious benefits for people buying second-hand vehicles, garages
that service vehicles and service stations where petrol thefts can regularly be
associated with stolen vehicles."&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;"Potentially, it gives police many more pairs of eyes out there. People can do
their own checking and then report it to Police."
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This sounds like a goldmine of interesting data. I grabbed the list of all the cars stolen in the last six months. It comes in a handy CSV file. For example, here&amp;#8217;s the first four vehicles:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Plate,Color,Make,Model,Year,Type,Date,Region
007579,Blue,Yamaha,TTR230,2007,Trail Bike,2011-07-14,Bay of Plenty
0BOOST,Blue,Honda,ACCORD,2003,Saloon,2011-06-19,Counties/Manukau
1045Z,Orange,Trailer,HOMEMADE,1972,Trailer,2011-11-07,Eastern
1079Y,Silver,Trailer,ABEL K8SSA,2001,Trailer,2011-07-14,Waitemata
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So I decided to have a crack at visualising the data. Above is the first interactive graphic I&amp;#8217;ve published - the most popular makes of stolen vehicles.&lt;/p&gt;

&lt;h3 id='visualisation_tech'&gt;Visualisation Tech&lt;/h3&gt;

&lt;p&gt;This visualisation was a great excuse to play around with some new tech. Rendering is done with SVG, controlled by the excellent &lt;a href='http://mbostock.github.com/d3/'&gt;d3 visualisation library&lt;/a&gt;. Popovers are care of &lt;a href='http://twitter.github.com/bootstrap/'&gt;Twitter Bootstrap&lt;/a&gt;, which rocks, although I did have to put in a &lt;a href='https://github.com/twitter/bootstrap/pull/744'&gt;pull request with fixing the popovers for SVG&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sorry Android 2.3 users, your browser doesn&amp;#8217;t do SVG, so you&amp;#8217;ll need to use a desktop browser to see.&lt;/p&gt;

&lt;p&gt;I was very impressed with d3&amp;#8217;s flexibility and conciseness, and I&amp;#8217;m looking forward to using it on more projects. I may blog about how awesome the d3 experience was later. If you&amp;#8217;re into making visualisations, I heartily recommend checking d3 out.&lt;/p&gt;
&lt;style&gt;
.highlight {
    fill-opacity: 0; 
}
.carBox {
    width: 5px;
    height: 10px;
    display: inline-block;
    border: 1px solid black;
    line-height: 6px;
}
/* nicked from bootstrap */
.popover {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1000;
  padding: 5px;
  display: none;
}
.popover.above .arrow {
  bottom: 0;
  left: 50%;
  margin-left: -5px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #000000;
}
.popover.right .arrow {
  top: 50%;
  left: 0;
  margin-top: -5px;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-right: 5px solid #000000;
}
.popover.below .arrow {
  top: 0;
  left: 50%;
  margin-left: -5px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid #000000;
}
.popover.left .arrow {
  top: 50%;
  right: 0;
  margin-top: -5px;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 5px solid #000000;
}
.popover .arrow {
  position: absolute;
  width: 0;
  height: 0;
}
.popover .inner {
  background: #000000;
  background: rgba(0, 0, 0, 0.8);
  padding: 3px;
  overflow: hidden;
  width: 280px;
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  border-radius: 6px;
  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
  -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
  box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
}
.popover .title {
  background-color: #f5f5f5;
  padding: 9px 15px;
  line-height: 1;
  -webkit-border-radius: 3px 3px 0 0;
  -moz-border-radius: 3px 3px 0 0;
  border-radius: 3px 3px 0 0;
  border-bottom: 1px solid #eee;
}
.popover .content {
  background-color: #ffffff;
  padding: 14px;
  -webkit-border-radius: 0 0 3px 3px;
  -moz-border-radius: 0 0 3px 3px;
  border-radius: 0 0 3px 3px;
  -webkit-background-clip: padding-box;
  -moz-background-clip: padding-box;
  background-clip: padding-box;
}
.popover .content p, .popover .content ul, .popover .content ol {
  margin-bottom: 0;
}
.fade {
  -webkit-transition: opacity 0.15s linear;
  -moz-transition: opacity 0.15s linear;
  -ms-transition: opacity 0.15s linear;
  -o-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
  opacity: 0;
}
.fade.in {
  opacity: 1;
}
&lt;/style&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/d3.min.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/d3.csv.min.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/d3.time.min.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/underscore-min.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/backbone-min.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/bootstrap-twipsy.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/bootstrap-popover.js'&gt; &lt;/script&gt;&lt;script defer='true' src='/stolen-vehicles-pt1/main.js'&gt; &lt;/script&gt;</content>
 </entry>
 
 <entry>
   <title>Automatically Compiling Haml in Vim</title>
   <link href="http://www.markhansen.co.nz/autocompiling-haml/" />
   <updated>2011-12-02T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/autocompiling-haml</id>
   <content type="html">&lt;p&gt;I don&amp;#8217;t write a lot of straight HTML any more - I prefer the rapid prototyping you can do with the likes of Haml, without having to worry about always matching your start and end tags.&lt;/p&gt;

&lt;p&gt;However, the main disadvantage of haml is that it needs to be compiled to HTML. This is an extra step in development that slows down iteration.&lt;/p&gt;

&lt;p&gt;Previously I used a &lt;a href='https://github.com/mynyml/watchr'&gt;watchr&lt;/a&gt; script, spinning up a process that watches for new haml files and automatically compiles them. This isn&amp;#8217;t as seamless as I&amp;#8217;d like, because I have to remember to spin up this process every time I want to write some haml. Also, watchr won&amp;#8217;t pick up new files without a restart.&lt;/p&gt;

&lt;p&gt;But I don&amp;#8217;t want to auto compile every haml file. My rails or jekyll templates are supposed to be substituted into templates, not rendered as-is. I want a way to opt in to auto-compilation, preferably only once per directory.&lt;/p&gt;

&lt;p&gt;To opt-in, my script checks if a file named &amp;#8220;.autohaml&amp;#8221; exists in the current directory. Create a file named &amp;#8220;.autohaml&amp;#8221; to opt in.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve added this autocompile code to my vimrc. I&amp;#8217;ve tried to use the minimum of vimscript possible, doing most of the logic using python.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='vim'&gt;&lt;span class='c'&gt;&amp;quot; Auto compile .haml files on save, but only&lt;/span&gt;
&lt;span class='c'&gt;&amp;quot; if there&amp;#39;s a .autocompilehaml file in the cwd.&lt;/span&gt;
&lt;span class='c'&gt;&amp;quot; Depends on a `haml` executable. `sudo gem install haml`&lt;/span&gt;

au &lt;span class='nb'&gt;BufWritePost&lt;/span&gt; *.haml &lt;span class='k'&gt;call&lt;/span&gt; HamlMake&lt;span class='p'&gt;()&lt;/span&gt;

&lt;span class='k'&gt;function&lt;/span&gt;&lt;span class='p'&gt;!&lt;/span&gt; HamlMake&lt;span class='p'&gt;()&lt;/span&gt;
    &lt;span class='k'&gt;py&lt;/span&gt; &lt;span class='p'&gt;&amp;lt;&amp;lt;&lt;/span&gt; ENDOFPYTHON
import os
import &lt;span class='k'&gt;vim&lt;/span&gt;

in_file &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='k'&gt;vim&lt;/span&gt;.current.buffer.name
dirname &lt;span class='p'&gt;=&lt;/span&gt; os.&lt;span class='nb'&gt;path&lt;/span&gt;.dirname&lt;span class='p'&gt;(&lt;/span&gt;in_file&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;if&lt;/span&gt; os.&lt;span class='nb'&gt;path&lt;/span&gt;.exists&lt;span class='p'&gt;(&lt;/span&gt;dirname &lt;span class='p'&gt;+&lt;/span&gt; &lt;span class='c'&gt;&amp;quot;/.autohaml&amp;quot;):&lt;/span&gt;
    out_file &lt;span class='p'&gt;=&lt;/span&gt; in_file[&lt;span class='m'&gt;0&lt;/span&gt;:&lt;span class='m'&gt;-5&lt;/span&gt;] &lt;span class='p'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;.html&amp;quot;&lt;/span&gt;
    os.system&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;haml %s &amp;gt; %s&amp;quot;&lt;/span&gt; % &lt;span class='p'&gt;(&lt;/span&gt;in_file&lt;span class='p'&gt;,&lt;/span&gt; out_file&lt;span class='p'&gt;))&lt;/span&gt;

ENDOFPYTHON
&lt;span class='k'&gt;endfunction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>A Visualisation of Your Last.FM History</title>
   <link href="http://www.markhansen.co.nz/lastfm-scattergraph/" />
   <updated>2011-10-31T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/lastfm-scattergraph</id>
   <content type="html">&lt;p&gt;Today, I&amp;#8217;m launching &lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt;, a new visualisation that shows &lt;a href='http://last.fm/'&gt;Last.fm&lt;/a&gt; users how their listening habits change over time.&lt;/p&gt;
&lt;a href='/scatter.fm/'&gt;
&lt;img alt='Screenshot of Scatter.FM' src='/images/scatterfm/screenshot.png' /&gt;
&lt;/a&gt;
&lt;p&gt;If you&amp;#8217;ve been a Last.fm user for any length of time, you can use &lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt; to visualise your entire listening history.&lt;/p&gt;
&lt;div class='superquote'&gt;
Oh yeah... I remember that time when we were listening to that!
&lt;/div&gt;
&lt;p&gt;I associate memories with the music I was listening to at the time. It&amp;#8217;s possible to go the other way: unlocking &amp;#8216;forgotten&amp;#8217; memories of good times with friends by seeing what music you were listening to.&lt;/p&gt;
&lt;div class='superquote'&gt;
I remember the first time I heard that song...
&lt;/div&gt;
&lt;p&gt;This is my favourite thing about &lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt;, remembering good times from the past. Using &lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt;, I can see parties where my iPod DJ&amp;#8217;d, study sessions leading up to exams, late night hacking sessions, roadtrips, holidays (sparse areas on the graph), and times overseas (the graph is time-shifted).&lt;/p&gt;
&lt;div class='superquote'&gt;
I remember when I had that album on repeat for three days straight...
&lt;/div&gt;
&lt;p&gt;Big life changes often precipitate changes in listening habits - you can see these changes in the graph, reflecting your story.&lt;/p&gt;

&lt;h3 id='what_does_it_do'&gt;What does it do?&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt; extracts the list of songs you&amp;#8217;ve listened to from Last.fm&amp;#8217;s servers, and plots every song on a scatterplot, so you can see how your listening habits evolve over time.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;Scatter.FM&lt;/a&gt; plots every song in a Last.fm user&amp;#8217;s account as a dot in a graph, plotted by days (x-axis) and time of day (y-axis).&lt;/p&gt;

&lt;p&gt;You can hover over any point to see information about the song, the exact time you listened to it, and album art. The graph will show you other times you played the same song by flashing the other dots of the same song.&lt;/p&gt;

&lt;p&gt;Your top artists are assigned distict colors so they stand out, and you can filter the displayed data by artist, album, and track using the &amp;#8216;Filter Songs&amp;#8217; box at the top.&lt;/p&gt;

&lt;p&gt;If you have an extra-long listening history, you can zoom and pan in on specific days by double-clicking.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I hope you enjoy! This has been a fun project, and helped bring back memories of a lot of good times. Hopefully it can do the same for other people.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.markhansen.co.nz/scatter.fm/'&gt;[Scatter.FM]&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Unity+XMonad in Ubuntu 11.10 Oneiric</title>
   <link href="http://www.markhansen.co.nz/xmonad-ubuntu-oneiric/" />
   <updated>2011-10-17T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/xmonad-ubuntu-oneiric</id>
   <content type="html">&lt;p&gt;I love XMonad. For years I&amp;#8217;ve been using it inside Gnome 2, but with the release of Ubuntu 11.10 Oneiric, Gnome 2 is on the way out, and Unity is the way forward. Here&amp;#8217;s how to run XMonad with Unity-2D:&lt;/p&gt;

&lt;p&gt;1) Install XMonad. Open a terminal and enter&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;sudo apt-get install xmonad
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;2) Configure XMonad to interact happily with unity. This involves floating the laucher over the top of the active window, and not trying to tile the top panel.&lt;/p&gt;

&lt;p&gt;Make a file &lt;code&gt;~/.xmonad/xmonad.hs&lt;/code&gt;, and put in it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='haskell'&gt;&lt;span class='kr'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;XMonad&lt;/span&gt;
&lt;span class='kr'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;XMonad.Config.Gnome&lt;/span&gt;

&lt;span class='nf'&gt;myManageHook&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;composeAll&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;
    &lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='n'&gt;manageHook&lt;/span&gt; &lt;span class='n'&gt;gnomeConfig&lt;/span&gt;
    &lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;className&lt;/span&gt; &lt;span class='o'&gt;=?&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Unity-2d-panel&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;--&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;doIgnore&lt;/span&gt;
    &lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;className&lt;/span&gt; &lt;span class='o'&gt;=?&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Unity-2d-launcher&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;--&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;doFloat&lt;/span&gt;
    &lt;span class='p'&gt;])&lt;/span&gt;

&lt;span class='nf'&gt;main&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;xmonad&lt;/span&gt; &lt;span class='n'&gt;gnomeConfig&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;manageHook&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;myManageHook&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;3) Compile this config file in the terminal&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;xmonad --recompile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;4) Tie it all together with an alternative &amp;#8220;XMonad Unity&amp;#8221; XSession.&lt;/p&gt;

&lt;p&gt;Make a file &lt;code&gt;/usr/share/gnome-session/sessions/xmonad.session&lt;/code&gt; with these lines:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ini'&gt;&lt;span class='k'&gt;[GNOME Session]&lt;/span&gt;
&lt;span class='na'&gt;Name&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;Xmonad Unity&lt;/span&gt;
&lt;span class='na'&gt;RequiredComponents&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;gnome-settings-daemon;&lt;/span&gt;
&lt;span class='na'&gt;RequiredProviders&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;windowmanager;panel;launcher;&lt;/span&gt;
&lt;span class='na'&gt;DefaultProvider-windowmanager&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;xmonad&lt;/span&gt;
&lt;span class='na'&gt;DefaultProvider-panel&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;unity-2d-panel&lt;/span&gt;
&lt;span class='na'&gt;DefaultProvider-launcher&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;unity-2d-launcher&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Make a file &lt;code&gt;/usr/share/xsessions/xmonad-unity-session.desktop&lt;/code&gt; with these lines:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ini'&gt;&lt;span class='k'&gt;[Desktop Entry]&lt;/span&gt;
&lt;span class='na'&gt;Name&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;XMonad Unity&lt;/span&gt;
&lt;span class='na'&gt;Comment&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;Tiling window manager&lt;/span&gt;
&lt;span class='na'&gt;TryExec&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;/usr/bin/gnome-session&lt;/span&gt;
&lt;span class='na'&gt;Exec&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;gnome-session --session=xmonad&lt;/span&gt;
&lt;span class='na'&gt;Type&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;XSession&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And you&amp;#8217;re done! Logout, and log back in, selecting the &amp;#8220;XMonad Unity&amp;#8221; session. The Unity panel and launcher will happily coexist with XMonad. Choice!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A New Map of New Zealand's Wireless Networks</title>
   <link href="http://www.markhansen.co.nz/nz-wireless-map/" />
   <updated>2011-08-24T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/nz-wireless-map</id>
   <content type="html">&lt;img alt='Mt Te Aroha Antenna Mast' src='/images/nzwirelessmap/mttearoha.jpg' class='aligncenter' /&gt;&lt;em&gt;Mt Te Aroha Antenna Mast (Photo Credit: &lt;a href='http://joeloughton.com'&gt;Joel Oughton&lt;/a&gt;)&lt;/em&gt;
&lt;p&gt;I&amp;#8217;ve just launched a new visualisation: a &lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;map of New Zealand&amp;#8217;s terrestrial Radio/Wireless network&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a map that draws lines showing the links between antennae like the one shown at the right. You might have seen these towers on top of hills while driving. I always wondered what they were used for, and where they connected to. Now you can see where the links go, and who they&amp;#8217;re for!&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s not just huge antenna mast towers like the one shown on the right. Hospitals, big businesses, cell towers, weather stations, and offshore oil rigs are connected with these radio links.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m really excited about being able to visualise this data - the map shows over 17,000 locations, and 26,000 point-to-point links over the whole country!&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the visualisation: &lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;NZ Wireless Map&lt;/a&gt;. Check it out!&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s just a few interesting things I found exploring the data:&lt;/p&gt;

&lt;h3 id='lake_rotorua'&gt;Lake Rotorua&lt;/h3&gt;
&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;
&lt;img alt='Lake Rotorua' src='/images/nzwirelessmap/lakerotorua.png' /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;Lakes are awesome to transmit across! They stay flat, and usually have good hills on either side. Lake Rotorua demonstates this really well - here you can see how densely it&amp;#8217;s criscrossed with links.&lt;/p&gt;

&lt;h3 id='auckland_skytower'&gt;Auckland Skytower&lt;/h3&gt;
&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;
&lt;img alt='Skytower' src='/images/nzwirelessmap/skytower.png' /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;The busiest place I could find, with the most links converging on one location, was the Skytower in Auckland. Here dozens, if not hundreds of wireless links converge from all over the Auckland region.&lt;/p&gt;

&lt;h3 id='hamilton'&gt;Hamilton&lt;/h3&gt;
&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;
&lt;img alt='Hamilton' src='/images/nzwirelessmap/hamilton.png' /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;Hamilton&amp;#8217;s a very flat city, and there&amp;#8217;s not much in the way of mountain ranges nearby. I imagine this would make it difficult to transmit signals to the roofs of buildings in town. On the map, you can see how transmitting companies have dealt with this flatness - the few high buildings that do exist are used extensively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Hamilton Lake Water Tower (shown)&lt;/li&gt;

&lt;li&gt;Waikato Hospital&lt;/li&gt;

&lt;li&gt;WEL Building&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Signals spread all over town from these vantage points.&lt;/p&gt;

&lt;h3 id='taranaki_oilgas_fields'&gt;Taranaki Oil/Gas fields&lt;/h3&gt;
&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;
&lt;img alt='Oil Fields' src='/images/nzwirelessmap/oilfields.png' /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;You don&amp;#8217;t usually notice New Zealand&amp;#8217;s offshore gasfields on maps, but they really stick out on a map of wireless links. You can see the Maui A and Maui B platforms communicating through a host of links on the Taranaki shore, and the Kupe Gas field south of the mountain.&lt;/p&gt;

&lt;h3 id='white_island'&gt;White Island&lt;/h3&gt;
&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;
&lt;img alt='White Island' src='/images/nzwirelessmap/whiteisland.png' /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;p&gt;We even have a wireless link set up &lt;em&gt;to an active volcano&lt;/em&gt;. Awesome!&lt;/p&gt;

&lt;h3 id='views'&gt;Views&lt;/h3&gt;

&lt;p&gt;Exploring the map, I realised that it inadvertently highlights the best views in the country. Antenna masts are &lt;em&gt;specifically placed&lt;/em&gt; for great views in all directions. Lots of research must go into finding the places with these great views before spending vast amounts of money erecting a tower.&lt;/p&gt;

&lt;p&gt;Why not take advantage of all this research into great views next time you&amp;#8217;re deciding where to go hiking?&lt;/p&gt;

&lt;h2 id='getting_the_data_on_the_map'&gt;Getting the data on the map&lt;/h2&gt;

&lt;p&gt;If you&amp;#8217;ve got a nerdy streak, keep reading. This is where I explain the programming behind the visualisation. It&amp;#8217;s all open source, available on &lt;a href='https://github.com/mhansen/nzwirelessmap'&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A friend showed me &lt;a href='http://www.geekzone.co.nz/BarTender/7403'&gt;BarTender&amp;#8217;s work making maps of cell tower sites&lt;/a&gt; he made using &lt;a href='http://rsm.govt.nz/'&gt;Radio Spectrum Management&amp;#8217;s&lt;/a&gt; database. BarTender explains how he extracted the data from the Microsoft Access Database dump, into a SQLite database with mdb-sqlite, then used SQL queries and XML tools to manipulate the data into KML files.&lt;/p&gt;

&lt;p&gt;I managed to dump the SQL out of the Access Database and import it into SQLite using &lt;a href='http://cltb.ojuba.org/en/articles/mdb2sqlite.html'&gt;these instructions&lt;/a&gt;. Then the data was all mine to mess around with!&lt;/p&gt;

&lt;h3 id='exploring_the_database'&gt;Exploring The Database&lt;/h3&gt;

&lt;p&gt;I found the important tables (&lt;a href='https://gist.github.com/1167349'&gt;here&amp;#8217;s the full schema&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Licence&lt;/strong&gt;: A licence to use the airways granted to a company. Usually this has one or more ReceiveConfigurations and TransmitConfigurations.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ReceiveConfiguration&lt;/strong&gt; and &lt;strong&gt;TransmitConfiguration&lt;/strong&gt;. These tables give information on locations, antenna equipment, direction, and height.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;: This table gives each location a name, height. However, you need to join with GeographicReference to get Latitudes and Longitudes.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GeographicReference&lt;/strong&gt;: NZ uses a whole lot of geodetic datums, and this table holds the location of each antenna in every different format. We&amp;#8217;re only interested in WGS84, the worldwide format that Google Maps uses. This table will give us the Latitude and Longitude of each location.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I crafted an SQL query to select pairs of towers, but it was incredibly slow. I put a few indexes on ID fields of the tables I used, and then the query ran in less than a second. Awesome.&lt;/p&gt;

&lt;h3 id='plotting_the_lines'&gt;Plotting the lines&lt;/h3&gt;

&lt;p&gt;I wrote a python script to manipulate these transmit-receive antenna pairs into KML, showing the pairs as lines on a map. I hadn&amp;#8217;t used KML before, but, aside from being XML, it was very easy. The format is well documented, the only problems came when one of the names had an 0x19 &amp;#8220;ASCII device control 3&amp;#8221; character, which XML apparently can&amp;#8217;t represent. I removed the character, and everything worked swimmingly.&lt;/p&gt;

&lt;p&gt;However, the network was far too crowded with fake links, with far too many links going out into the middle of the sea. Upon investigation, these links were all the corners of a &amp;#8220;Receive Protection Area&amp;#8221; polygon - not an actual point-to-point link. I had to reverse engineer the database to figure out that point-to-point links are identified by &lt;code&gt;locationtypeid = 4&lt;/code&gt;, and then the map showed the real structure of the network.&lt;/p&gt;

&lt;p&gt;Huge lines were also stretching up to the equator, stretching out to geosynchronous satellites. These lines were really interesting, but they obfuscated the terrestrial links, so I removed the satellite links. I&amp;#8217;d like to add them back in somehow, maybe by using another marker on the ground where the uplinks are.&lt;/p&gt;

&lt;h3 id='putting_it_on_a_website'&gt;Putting it on a website&lt;/h3&gt;

&lt;p&gt;This was all great, but I can&amp;#8217;t expect people to download a KML file and open it in a desktop application. People expect data to be available in a web-based tool these days, and if it isn&amp;#8217;t, many people just won&amp;#8217;t bother.&lt;/p&gt;

&lt;p&gt;First of all, I tried hosting the KML on a server, and searching for the URL inside google maps, just like BarTender has done with his cellphone maps &lt;a href='http://maps.google.co.nz/maps?f=q&amp;amp;hl=en&amp;amp;q=http://sites.google.com/site/nzcellinfo/Telecom.kml'&gt;(here&amp;#8217;s an example)&lt;/a&gt;. However, &lt;a href='http://code.google.com/apis/kml/documentation/mapsSupport.html'&gt;Google Maps has specific limits&lt;/a&gt; on the number of features it will plot: 1000 data points, and 10MB of KML. I had over ten thousand features, and 20MB of KML. This wasn&amp;#8217;t going to work.&lt;/p&gt;

&lt;h3 id='fusion_tables'&gt;Fusion Tables&lt;/h3&gt;

&lt;p&gt;There&amp;#8217;s a way around this, by using &lt;a href='https://www.google.com/fusiontables'&gt;Google Fusion Tables&lt;/a&gt;. Fusion Tables is one of my favourite tools for visualisation. [Disclaimer: I will be working at Google, but I don&amp;#8217;t know anyone on the Fusion Tables team. I just think the work they do is awesome]&lt;/p&gt;

&lt;p&gt;Fusion Tables is like a spreadsheet program, but with specific support for geographic data types: placemarks, routes, polygons. It comes with a half-dozen visualisation methods, including &amp;#8220;Map&amp;#8221; view, where it can plot KML on a map. With Fusion Tables, there&amp;#8217;s no limit to the amount of points you can plot on the map. Perfect!&lt;/p&gt;

&lt;p&gt;I repurposed my KML exporter into a TSV exporter, and uploaded the data to Fusion Tables. You can then specify what information you want in the popup when a user clicks on a line - I made it show the receiver, transmitter, licence id, and licencee. and made the lines a bit thinner and greener.&lt;/p&gt;

&lt;p&gt;Fusion Tables makes it almost criminally easy to make interactive geographic visualisations. I&amp;#8217;m a huge fan.&lt;/p&gt;

&lt;h3 id='thanks'&gt;Thanks&lt;/h3&gt;

&lt;p&gt;Many thanks to the people at &lt;a href='http://rsm.govt.nz/'&gt;Radio Spectrum Management&lt;/a&gt; in the Ministry of Economic Development. They&amp;#8217;ve made public a &lt;a href='http://www.rsm.govt.nz/cms/tools-and-services/spectrum-search-lite'&gt;very high-quality dataset containing all the radio licences in New Zealand&lt;/a&gt;. Usually when dealing with datasets with tens of thousands of points, there&amp;#8217;s a few problems, but this dataset is pristine. This wouldn&amp;#8217;t have been possible without their hard work. Cheers!&lt;/p&gt;

&lt;p&gt;Have a look, go exploring, and let me know in the blog comments if you find something interesting. Feedback is much appreciated!&lt;/p&gt;

&lt;p&gt;[&lt;a href='http://wirelessmap.markhansen.co.nz/'&gt;NZ Wireless Map&lt;/a&gt;]&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Visualising Auckland's Public Transit</title>
   <link href="http://www.markhansen.co.nz/auckland-transit-map/" />
   <updated>2011-06-17T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/auckland-transit-map</id>
   <content type="html">&lt;p&gt;&lt;a href='http://sciblogs.co.nz/seeing-data/'&gt;Chris McDowall&lt;/a&gt; has made a wonderful visualisation of Auckland&amp;#8217;s Transit data. He&amp;#8217;s taken the Google Transit Feed data from Maxx, and mashed it up using Python/Matplotlib/Basemap/FFmpeg/Vimeo to deliver a &lt;a href='http://sciblogs.co.nz/seeing-data/2011/01/20/an-animated-map-of-aucklands-public-transport-network/'&gt;birds-eye view of Auckland&amp;#8217;s transit system over time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m keen to do something similar for Hamilton&amp;#8217;s transport network. Hamilton has recently integrated their bus system with the &lt;a href='http://code.google.com/transit/spec/transit_feed_specification.html'&gt;Google Transit Feed API&lt;/a&gt;, so I know there must be the data I need sitting publicly available on some web server somewhere, in delicious plain CSV format. I&amp;#8217;m just not sure where. I&amp;#8217;ve asked &lt;a href='http://www.busit.co.nz/'&gt;Busit!&lt;/a&gt; if they can point me in the right direction, so watch this space.&lt;/p&gt;

&lt;p&gt;Chris has made a lot of other &lt;a href='http://sciblogs.co.nz/seeing-data/'&gt;excellent visualisations&lt;/a&gt;, they&amp;#8217;re pretty cool. &lt;a href='http://sciblogs.co.nz/seeing-data/'&gt;Check them out&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hamilton's Bridges in Fog</title>
   <link href="http://www.markhansen.co.nz/bridgefog/" />
   <updated>2011-06-13T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/bridgefog</id>
   <content type="html">&lt;p&gt;Lights have been attached to the Bridge St Bridge, and they look amazing in Hamilton&amp;#8217;s signature thick fog. The fog&amp;#8217;s usually pretty thick, but it&amp;#8217;s even thicker along the banks of the Waikato River, which these bridges cross.&lt;/p&gt;

&lt;p&gt;I got a chance to snap some pictures of Bridge St bridge a few nights ago, along with the Fairfield bridge and The Base.&lt;/p&gt;

&lt;p&gt;Click to embiggen:&lt;/p&gt;
&lt;div class='gallery'&gt;
&lt;a title='Bridge St Bridge, Hamilton' href='/images/bridgefog/bridge-st-blue.jpg'&gt;
    &lt;img src='/images/bridgefog/bridge-st-blue.jpg' /&gt;
&lt;/a&gt;
&lt;a title='Fairfield Bridge, Hamilton' href='/images/bridgefog/fairfield-bridge.jpg'&gt;
    &lt;img src='/images/bridgefog/fairfield-bridge.jpg' /&gt;
&lt;/a&gt;
&lt;a title='Bridge St Bridge, Hamilton' href='/images/bridgefog/bridge-st-pink.jpg'&gt;
    &lt;img src='/images/bridgefog/bridge-st-pink.jpg' /&gt;
&lt;/a&gt;
&lt;a title='The Base Shopping Centre, Te Rapa, Hamilton' href='/images/bridgefog/thebase.jpg'&gt;
    &lt;img src='/images/bridgefog/thebase.jpg' /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Fog photos are a small obsession of mine. This time last year, I took some &lt;a href='/fog/'&gt;fog photos of Waikato University&lt;/a&gt;. Do you know any other areas in Hamilton that are amazing in the fog?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Visualising the New Zealand Government Budget</title>
   <link href="http://www.markhansen.co.nz/budget-visualisation/" />
   <updated>2011-05-19T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/budget-visualisation</id>
   <content type="html">&lt;p&gt;I never used to care about the government budget. Every year, I&amp;#8217;d see a storm of Budget stories on the news, and I wouldn&amp;#8217;t understand any of the numbers they were throwing about. $50 million cuts to education. $2 billion for fibre broadband. $200 million increases for student loans.&lt;/p&gt;

&lt;p&gt;I knew these were big numbers, but I can&amp;#8217;t reason about them. Are they huge? Or are they pocket change, compared to the government balance? Are they going to bankrupt our country? I just didn&amp;#8217;t know. I didn&amp;#8217;t have any context, so I couldn&amp;#8217;t reason about these huge numbers. I got frustrated, and I didn&amp;#8217;t pay attention.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s a shame, because the Budget is arguably the most important thing the government does. It decides funding for every aspect of the government, where the money comes from, and where the money goes. It distributes billions of dollars, impacting every one of us, and shaping the future of the country.&lt;/p&gt;

&lt;p&gt;And yet, it&amp;#8217;s inscrutable. The data is available, but it&amp;#8217;s buried deep in spreadsheets - which is great if you want to do hardcore analysis of the data, but not for interactive exploring.&lt;/p&gt;

&lt;h3 id='presenting_a_visualisation'&gt;Presenting: A Visualisation&lt;/h3&gt;

&lt;p&gt;Today, with the announcement of the 2011 Budget, we&amp;#8217;re launching &lt;a href='http://wheresmytaxes.co.nz'&gt;Where&amp;#8217;s My Taxes?&lt;/a&gt; , a visualisation of what the goverment&amp;#8217;s spending your money on.&lt;/p&gt;

&lt;p&gt;With this website, we let you explore goverment expenses, and bring huge numbers into context by showing the the &lt;em&gt;per capita&lt;/em&gt; levels of spending of each item.&lt;/p&gt;

&lt;p&gt;Picking an example at random, it&amp;#8217;s very difficult for me to reason about a $250 million spend on Pacific aid. Is it high? Is it low? I don&amp;#8217;t know! But when you convert it to per capita spending - it comes out at $57 per person - that&amp;#8217;s a number that&amp;#8217;s easy to reason about. &amp;#8220;That&amp;#8217;s two boxes of beer!&amp;#8221;.&lt;/p&gt;

&lt;p&gt;As another random example, look at the Student Allowance. $660 million spending per year, according to the budget. That&amp;#8217;s got very little context, but when you work it out to be $148 per person, again, it&amp;#8217;s a lot easier to reason about the costs/benefits, when you can see the average cost to &lt;em&gt;you&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s also a lot easier to see the relative importance of each government Department when you plot it as a pie chart. It&amp;#8217;s easy to see, for example, that the Police cost less than the Defence force, and the Department of Conservation is a tiny fraction of the cost of Health and Education.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I hope that this website helps people understand where their taxes are going. Better informed voters can only lead to better governent.&lt;/p&gt;

&lt;h3 id='thanks'&gt;Thanks&lt;/h3&gt;

&lt;p&gt;Thanks to Luke Bjerring, my partner in this assignment, and Ryan Delaney, for whipping up an excellent design on very short notice.&lt;/p&gt;

&lt;p&gt;We took a lot of inspiration from the &lt;a href='http://datavizchallenge.org/'&gt;DataVizChallenge&lt;/a&gt;, a challenge to visualise US goverment taxes. There are some amazing visualisations of the US budget, and I applied some of these techniques to visualise the New Zealand data. In particular, I want to thank &lt;a href='http://www.wheredidmytaxdollarsgo.com/'&gt;Where Did My Tax Dollars Go?&lt;/a&gt;, an excellent visualisation that provided a lot of inspiration for this project.&lt;/p&gt;

&lt;p&gt;This was developed as a project for the Information Visualisation class at the University of Waikato. Cheers to our lecturer, Mark Apperley, for giving us the freedom to pursue whatever visualisation we like.&lt;/p&gt;

&lt;p&gt;[&lt;a href='http://wheresmytaxes.co.nz'&gt;Where&amp;#8217;s My Taxes?&lt;/a&gt;]&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I'm interning at Google!</title>
   <link href="http://www.markhansen.co.nz/google-internship/" />
   <updated>2010-10-27T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/google-internship</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m interning at Google Sydney!&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve just accepted their internship offer for three months over the summer. I&amp;#8217;ll be relocating to Sydney till February next year.&lt;/p&gt;

&lt;p&gt;This is pretty much a dream come true for me - Google&amp;#8217;s got a &lt;a href='http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html'&gt;huge&lt;/a&gt; &lt;a href='http://www.kaushik.net/avinash/2008/02/10-insights-from-11-months-of-working-at-google.html'&gt;reputation&lt;/a&gt; as a great place for developers to work.&lt;/p&gt;

&lt;p&gt;Good times are expected!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;My preparation for the interviews:&lt;/p&gt;
&lt;img alt='I checked out the entire computer science dept of the Uni library' src='/images/books.jpg' /&gt;
&lt;p&gt;I checked out as many books as I could carry (go the uni library!). Books on networks, algorithms, methodology, languages, parallel programming - anything I could get my hands on.&lt;/p&gt;

&lt;p&gt;In the interviews, we talked about designing for scale, languages, algorithms (lots of algorithms) - all the juicy bits of Computer Science. We even did some live coding via Google Docs. It was really challenging, and I&amp;#8217;m lucky to have got through.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m pretty excited. This is shaping up to be a great summer!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Awesome Small Software: Watch</title>
   <link href="http://www.markhansen.co.nz/awesome-software-watch/" />
   <updated>2010-09-03T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/awesome-software-watch</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m starting a small series where I do shout-outs to my favorite bits of software - software that&amp;#8217;s just &lt;strong&gt;awesome&lt;/strong&gt;. Software that will make your life easier. Software that you want to know about.&lt;/p&gt;

&lt;p&gt;As a political statement, I&amp;#8217;ll be focussing on small software. I particularly like software that does one thing, and does it well. &lt;strong&gt;I love small software.&lt;/strong&gt; It&amp;#8217;s more maintainable, easier to understand, and more likely to be correct.&lt;/p&gt;

&lt;p&gt;Small software is inherently more flexible than large software, because it&amp;#8217;s easier to understand the small software to the point where you can change it.&lt;/p&gt;

&lt;p&gt;One of my favorite small pieces of software is &lt;code&gt;watch&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='ok_what_does_watch_do'&gt;Ok&amp;#8230; what does watch do?&lt;/h2&gt;

&lt;p&gt;In general, you need to run a bit of code, and you need it running often, sometimes in the background while you&amp;#8217;re working. &lt;code&gt;watch&lt;/code&gt; lets you run arbitrary code, repeatedly every few seconds. &lt;code&gt;watch program&lt;/code&gt; runs &lt;code&gt;program&lt;/code&gt; every 2 seconds, and displays the output.&lt;/p&gt;

&lt;h2 id='give_me_some_examples_man'&gt;Give me some examples, man!&lt;/h2&gt;

&lt;p&gt;Sure thing!&lt;/p&gt;

&lt;p&gt;You&amp;#8217;re working with javascript, and you&amp;#8217;re getting sick of syntax errors. It seems every time you reopen your site, things just aren&amp;#8217;t working as you&amp;#8217;d expect. you&amp;#8217;ve missed a semicolon somewhere, or misspelled a function. Stupid mistakes. And you&amp;#8217;ve got to switch over to the browser console to find these errors, then copy the line number back into your editor, navigate to the line, and look through the line to try to spot your error.&lt;/p&gt;

&lt;p&gt;If only there was some way to let me know immediately as soon as i made a mistake! &lt;code&gt;watch&lt;/code&gt; and &lt;code&gt;jslint&lt;/code&gt; to the rescue!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# jslint knows when you make mistakes in javascript&lt;/span&gt;
watch jslint *.js
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;Of couse, that last example was silly. You&amp;#8217;ve got 100% coverage with your test suite on all your code, because you&amp;#8217;ve diligently practiced TDD. (right?) Better to actually run your code, exercise it, and flush out the real bugs along with the syntax errors.&lt;/p&gt;

&lt;p&gt;Doing this manually sucks - leaving your editor, running the tests, then coming back to your editor takes valuable time. It&amp;#8217;d be great if the tests could be run continuously - then you&amp;#8217;d catch bugs &lt;em&gt;as you make them&lt;/em&gt;, and you won&amp;#8217;t have to backtrack/search to find where the bug is.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;watch runtests.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;You&amp;#8217;re working in a templating language (TeX, markdown, haml, whatever), and there&amp;#8217;s this stupid error - you&amp;#8217;re not escaping some character somewhere, and everything&amp;#8217;s been thrown off. You want to see the compiled output as you&amp;#8217;re working on the file, so you know immediately when you&amp;#8217;ve fixed the problem:&lt;/p&gt;

&lt;p&gt;Of course, you could edit, exit your editor, recompile the document, open the result, see what&amp;#8217;s changed, then switch back to your editor, clean up some more, exit your editor, recompile again, open the result again, see that it&amp;#8217;s still not fixed&amp;#8230;&lt;/p&gt;

&lt;p&gt;But you don&amp;#8217;t hate yourself: you want to shorten this whole write-compile-debug loop. So you open up a terminal next to your editor, firing up your good friend &lt;code&gt;watch&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# continuously compile my markdown report and display the html&lt;/span&gt;
watch markdown COMP301_final_report.markdown
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;You&amp;#8217;re waiting on this massive download of (completely legal, creative-commons licensed) music. You want to know the second it appears finished in your download folder:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;watch ls -l ~/Downloads
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;You&amp;#8217;re on a shared box, and it&amp;#8217;s going dog-slow. What the hell are the other users up to?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# programs that aren&amp;#39;t mine, and aren&amp;#39;t system&lt;/span&gt;
watch &lt;span class='s1'&gt;&amp;#39;ps aux | grep -v mark | grep -v root&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;You&amp;#8217;re debugging an HTTP API, and you want to see the full response to a request as you modify the backend. This is a DELETE method, and your browser only supports GET and POST. Refreshing in-browser isn&amp;#8217;t going to cut it. This would be better served as a unit test, but you&amp;#8217;re doing exploratory programming and want to see the result of what you&amp;#8217;re doing in real time.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# keep on firing DELETE requests!&lt;/span&gt;
watch &lt;span class='s1'&gt;&amp;#39;curl -X DELETE http://testserver.markhansen.co.nz/api/testpage&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;&lt;a href='http://1-day.co.nz'&gt;1-day&lt;/a&gt; is running one of their crazy &amp;#8216;new items every few minutes&amp;#8217; sales, and you want to know immediately if rock band drum kits come on sale, because you&amp;#8217;ve been wanting to learn the drums for ages, but you&amp;#8217;ve got no room for a real drumkit. Whatever - the electronic version is way fun anyway. You fire up &lt;code&gt;watch&lt;/code&gt; the keep an eye on the site&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# gimme them bargains!&lt;/span&gt;
watch &lt;span class='s1'&gt;&amp;#39;curl www.1-day.co.nz | grep -i &amp;quot;rock band&amp;quot;&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;p&gt;You keep tabbing around in your trusty IDE, (vim, naturally) but sometimes the jump-to-function fails - your tag cache is stale! You&amp;#8217;re sick and tired of exiting to the console and rebuilding to the taglist every time this happens, so you fire up a background terminal and call on your trusty friend &lt;code&gt;watch&lt;/code&gt; to do it for you, every 2 seconds:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# ctags, work your magic analyzing my code!&lt;/span&gt;
watch ctags my_code_directory -R
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;hr /&gt;
&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It&amp;#8217;s really useful to get (almost) real time status updates on almost anything. I use it whenever there&amp;#8217;s a long write-compile-debug cycle where the recompiling could be automated.&lt;/p&gt;

&lt;p&gt;It really shines with interpreted languages, where there&amp;#8217;s no compile wait and you get almost instant feedback, running your tests continuously.&lt;/p&gt;

&lt;p&gt;The default setting for &lt;code&gt;watch&lt;/code&gt; is to check your command every 2 seconds, but you can change this with the &lt;code&gt;-n&lt;/code&gt; option.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='c'&gt;# we have a lot of files, it&amp;#39;s going to take a while to make the tags db&lt;/span&gt;
&lt;span class='c'&gt;# give it 30 seconds&lt;/span&gt;
watch -n 30 ctags ~/awesomeproject/ -R
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Just knowing &lt;code&gt;watch&lt;/code&gt; exists, you&amp;#8217;re at a massive advantage whenever you need some task repeated. I&amp;#8217;ve found so many places where &lt;code&gt;watch&lt;/code&gt; is a natural fit. I bet you will too!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iPhone as Numberpad</title>
   <link href="http://www.markhansen.co.nz/iphone-as-numberpad/" />
   <updated>2010-08-01T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/iphone-as-numberpad</id>
   <content type="html">&lt;p&gt;I made a &lt;a href='http://github.com/mhansen/ipod-numeric-keypad'&gt;simple HTML5 iPhone app that displays a numeric keypad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt='Numberpad next to laptop' src='/images/ipod-numberpad.jpg' /&gt;&lt;/p&gt;

&lt;p&gt;My laptop doesn&amp;#8217;t have a numberpad, and I needed one for some of &lt;a href='http://www.blender.org'&gt;Blender&lt;/a&gt;&amp;#8217;s keyboard shortcuts. I was about to buy a USB numeric keypad, when I thought: If I call myself a programmer, I &lt;em&gt;should&lt;/em&gt; be able to make a numeric keypad. Screw paying for one! So I made one.&lt;/p&gt;

&lt;p&gt;When you touch one of the keys, it POSTs the key to a &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; server on my laptop, where &lt;a href='http://www.semicomplete.com/projects/xdotool/'&gt;xdotool&lt;/a&gt; sends the X11 event for the keypress to the active window.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s no force feedback, so this wouldn&amp;#8217;t do for serious data entry. But for triggering simple keyboard shortcuts, this works perfectly.&lt;/p&gt;

&lt;h3 id='thoughts'&gt;Thoughts:&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I&amp;#8217;m really grateful someone wrote xdotool so I don&amp;#8217;t have to get my hands dirty with the X11 C++ API.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;I love Sinatra. It&amp;#8217;s never been so easy to make a webapp, especially simple &amp;#8216;glue&amp;#8217; applications like this one. It really is a superbly simple framework, and it gets right out of your way. The whole serverside code was less than 50 lines, most of which my validation of keycodes:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='rb'&gt;&lt;span class='c1'&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;configure&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='c1'&gt;# make haml compile to html5 &lt;/span&gt;
    &lt;span class='n'&gt;set&lt;/span&gt; &lt;span class='ss'&gt;:haml&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:format&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:html5&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='c1'&gt;# compile views/index.haml &lt;/span&gt;
    &lt;span class='n'&gt;haml&lt;/span&gt; &lt;span class='ss'&gt;:index&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;post&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/press/:key&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='c1'&gt;# get the keycode for the numberpad key&lt;/span&gt;
    &lt;span class='n'&gt;keysym&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;keysyms&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:key&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
    &lt;span class='c1'&gt;# invoke xdotool to send the keypress to the active window&lt;/span&gt;
    &lt;span class='nb'&gt;system&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;xdotool key &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;keysym&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='c1'&gt;# keycode reference is at /usr/include/X11/keysymdef.h&lt;/span&gt;
&lt;span class='c1'&gt;# all of these are keypad events, so they start with &amp;#39;KP_&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;keysyms&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;zero&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_0&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;one&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;two&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;three&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_3&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;four&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_4&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;five&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_5&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;six&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_6&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;seven&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_7&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;eight&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_8&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;nine&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_9&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;

    &lt;span class='s1'&gt;&amp;#39;multiply&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Multiply&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;divide&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Divide&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;add&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Add&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;subtract&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Subtract&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;

    &lt;span class='s1'&gt;&amp;#39;decimal&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Decimal&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s1'&gt;&amp;#39;enter&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;KP_Enter&amp;#39;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href='http://haml-lang.com'&gt;Haml&lt;/a&gt; is excellent. It took 15 minutes to learn, and it made it so much faster to prototype new layout ideas. It was tricky to get the calculator aligned properly, but Haml made it easy to move bits of layout around, and change CSS classes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%html
  %head
    %meta(charset=&amp;#39;utf-8&amp;#39;)
    %meta(name=&amp;#39;viewport&amp;#39; content=&amp;#39;width=320; height=480; user-scalable=0;&amp;#39;)
    %title Numpad
    %link(rel=&amp;#39;stylesheet&amp;#39; href=&amp;#39;/site.css&amp;#39; type=&amp;#39;text/css&amp;#39; media=&amp;#39;screen&amp;#39; title=&amp;#39;default style sheet&amp;#39;)
  %body
    #content
      .row
        .nothing &amp;amp;nbsp;
        #divide /
        #multiply *
        #subtract -
      .row
        #seven 7
        #eight 8
        #nine 9
        #add.tall +
      .row
        #four 4
        #five 5
        #six 6
      .row
        #one 1
        #two 2
        #three 3
        #enter.tall ↵
      .row
        #zero.wide 0
        #decimal .
    %script(src=&amp;#39;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&amp;#39;)
    %script(src=&amp;#39;site.js&amp;#39;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adding a class was a simple matter of adding a &amp;#8216;.classname&amp;#8217; to the element. Removing an element, I didn&amp;#8217;t have to find and remove it&amp;#8217;s closing element, I just delete a line. The same for adding an element. It &lt;em&gt;feels&lt;/em&gt; a lot nicer than HTML. I might redo this site in Haml sometime.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='try_it'&gt;Try It&lt;/h2&gt;

&lt;p&gt;If you&amp;#8217;re on an X11 system, and have a phone with a browser, head over to the &lt;a href='http://github.com/mhansen/ipod-numeric-keypad'&gt;github page&lt;/a&gt; for installation instructions.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Your Language Influences your Thinking</title>
   <link href="http://www.markhansen.co.nz/languages-shape-thinking/" />
   <updated>2010-07-27T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/languages-shape-thinking</id>
   <content type="html">&lt;p&gt;There&amp;#8217;s a &lt;a href='http://online.wsj.com/article/SB10001424052748703467304575383131592767868.html'&gt;great article over at the Wall Street Journal&lt;/a&gt; about how language isn&amp;#8217;t a dumb, passive medium of data transport. Rather, language actively shapes our thoughts and ideas. It&amp;#8217;s a great article, &lt;a href='http://online.wsj.com/article/SB10001424052748703467304575383131592767868.html'&gt;go read it&lt;/a&gt;. I&amp;#8217;ll wait here.&lt;/p&gt;
&lt;blockquote&gt;
All this new research shows us that the languages we speak not only reflect or
express our thoughts, but also shape the very thoughts we wish to express. 

The structures that exist in our languages profoundly shape how we construct
reality.
&lt;/blockquote&gt;
&lt;p&gt;The same idea, expressed in different languages, is no longer the same idea. Each language carries different connotations:&lt;/p&gt;
&lt;blockquote&gt;
English speakers tend to say things like "John broke the vase" even for
accidents. Speakers of Spanish or Japanese would be more likely to say "the
vase broke itself."
&lt;/blockquote&gt;
&lt;p&gt;Each language embeds different details in its grammar:&lt;/p&gt;
&lt;blockquote&gt;
In Turkish, you would have to include in the verb how you acquired this
information. For example, if you saw the chubby fellow on the wall with your
own eyes, you'd use one form of the verb, but if you had simply read or heard
about it, you'd use a different form. 
&lt;/blockquote&gt;
&lt;p&gt;These subtle differences shape your thinking - different languages emphasise different aspects of the situation.&lt;/p&gt;

&lt;p&gt;You can see the same thing with programming languages! Functional languages like Haskell or Clojure favor verbs over nouns. Both these languages offer a multitude of functions that act on a small number of basic noun types. Using a functional language, you&amp;#8217;re likely to approach a problem by thinking about the functions needed - the data transformations, the procedures. The data takes a back seat - the &lt;strong&gt;act&lt;/strong&gt; is important, rather than the actor.&lt;/p&gt;

&lt;p&gt;Other languages offer a more noun-based approach (e.g. Java, C#). These languages offer first-class support for a large number of nouns (objects), where the object is the first-class citizen. Functions are only valid in the context of an object. Functions only exist as the children of objects. The &lt;strong&gt;actor&lt;/strong&gt; is important, not the act.&lt;/p&gt;

&lt;p&gt;Other languages offer a hybrid approach (e.g. JavaScript, Scala), offering a more-or-less equal footing between verbs and nouns. For example, Underscore.js (a JavaScript library) &lt;a href='http://documentcloud.github.com/underscore/#styles'&gt;offers the same operations with your choice of noun-first or verb-first grammar&lt;/a&gt;. I love this choice - it lets me choose the way I approach a problem. Some problems seem predominantly noun-based (e.g. modelling and simulating), but some problems seem more verb-based (e.g. dataflow, mathematics), and I get to choose the most readable approach for my domain.&lt;/p&gt;

&lt;p&gt;It goes further than functional/object-oriented grammar differences. For example Scheme programmers focus on building large solutions out of many smaller problems. The whole language embodies this - Scheme only defines a minimal set of primitives, and the rest of the language is built from combining these primitives.&lt;/p&gt;

&lt;p&gt;The good news: as developers, it&amp;#8217;s &lt;em&gt;easy&lt;/em&gt; to gain access to these different worldviews! It&amp;#8217;s relatively easy for us to pick up a new language - A new way of looking at the world. It&amp;#8217;s definitely a lot easier to learn a new computer language than to learn a new human language.&lt;/p&gt;

&lt;p&gt;Try something more exotic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Prolog&lt;/em&gt; - see problems in terms of logic!&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Erlang&lt;/em&gt; - gain a glimpse into their actor-based worldview.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Clojure&lt;/em&gt; - learn to live without changing any state.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;Haskell&lt;/em&gt; - live without any nouns at all! (while, hopefully, still getting stuff done)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any languages offering compellingly different worldviews that I left out? Leave a comment.&lt;/p&gt;

&lt;p&gt;See Also: - Steve Yegge&amp;#8217;s epic &lt;a href='http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html'&gt;&amp;#8216;Execution in the Kingdom of Nouns&amp;#8217;&lt;/a&gt;. If you&amp;#8217;re thinking &amp;#8216;nouns are all that we need anyway&amp;#8217;, you &lt;em&gt;need&lt;/em&gt; to read this.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Fog @ Waikato University</title>
   <link href="http://www.markhansen.co.nz/fog/" />
   <updated>2010-07-26T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/fog</id>
   <content type="html">&lt;p&gt;Hamilton gets heavy fog at night time.&lt;/p&gt;

&lt;p&gt;It plays with the lights at the university, turning downward-facing lamps into bright cones of light, turning spherical lights into ambient glowing orange, and turning groups of streetlights into aurora.&lt;/p&gt;

&lt;p&gt;Click to embiggen:&lt;/p&gt;
&lt;div class='gallery'&gt;
&lt;a title='Downward-facing lights make cones of illuminated fog on the College Hall walkway' href='/images/fog/cones.jpg'&gt;
    &lt;img src='/images/fog/cones.jpg' /&gt;
&lt;/a&gt;
&lt;a title='Orange lights by the Library' href='/images/fog/orange.jpg'&gt;
    &lt;img src='/images/fog/orange.jpg' /&gt;
&lt;/a&gt;
&lt;a title='Behind Oranga' href='/images/fog/oranga.jpg'&gt;
    &lt;img src='/images/fog/oranga.jpg' /&gt;
&lt;/a&gt;
&lt;a title='Walkway lights reflect on the lake' href='/images/fog/reflection.jpg'&gt;
    &lt;img src='/images/fog/reflection.jpg' /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;UPDATE June 2011&lt;/strong&gt;: I took some more fog photos, this time of &lt;a href='/bridgefog/'&gt;foggy Hamilton bridges&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Porting BASIC to JS</title>
   <link href="http://www.markhansen.co.nz/basic-to-js/" />
   <updated>2010-05-30T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/basic-to-js</id>
   <content type="html">&lt;p&gt;A few weeks ago, I heard one of my friends was trying to port some old BASIC code to PHP. (Why? I&amp;#8217;m still not sure.)&lt;/p&gt;

&lt;p&gt;Somehow, the mention of BASIC triggered some nostalgia for the days of cutting my teeth programming on the &lt;a href='http://en.wikipedia.org/wiki/Apple_iic'&gt;Apple IIc&lt;/a&gt;, typing in BASIC programs from a book. I had to have a go.&lt;/p&gt;

&lt;p&gt;So I ported the old code to JavaScript.&lt;/p&gt;

&lt;p&gt;It was a lot easier than I expected - mostly because both languages have global scope by default.&lt;/p&gt;

&lt;p&gt;JavaScript gives you the option of global or local scope every time you declare a variable - if you declare it with &lt;code&gt;var&lt;/code&gt; it is local to the function.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;a function-scoped variable&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;a global variable&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I never thought I&amp;#8217;d see global scope as a feature, but it really helps porting from BASIC :)&lt;/p&gt;

&lt;p&gt;The code tells you sunrise and sunset times anywhere in the world, so it uses a bit of trigonometry. BASIC defines the &lt;code&gt;SIN&lt;/code&gt;, &lt;code&gt;COS&lt;/code&gt;, &lt;code&gt;SQR&lt;/code&gt;, &lt;code&gt;ATN&lt;/code&gt;, and &lt;code&gt;SGN&lt;/code&gt; functions. Plugging these into JavaScript was easy:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;SIN&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sin&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;COS&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;cos&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;SQR&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sqrt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;ATN&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;Math&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;atan&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;SGN&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;num&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;num&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;num&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The rest of the code was just converting&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GOSUB&lt;/code&gt; -&amp;gt; function calls&lt;/li&gt;

&lt;li&gt;&lt;code&gt;GOTO&lt;/code&gt; -&amp;gt; &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; statements&lt;/li&gt;

&lt;li&gt;colons -&amp;gt; semicolons&lt;/li&gt;

&lt;li&gt;array indexing from one-based to zero-based&lt;/li&gt;

&lt;li&gt;removing line numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Easy.&lt;/p&gt;

&lt;p&gt;Of course, the code is &lt;a href='http://github.com/mhansen/suntimes'&gt;up on GitHub&lt;/a&gt;. I&amp;#8217;m a little disappointed GitHub doesn&amp;#8217;t have syntax highlighting for BASIC. ;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Gnome+XMonad in Ubuntu 10.04 Lucid</title>
   <link href="http://www.markhansen.co.nz/xmonad-ubuntu-lucid/" />
   <updated>2010-05-16T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/xmonad-ubuntu-lucid</id>
   <content type="html">&lt;p&gt;XMonad is a tiling window manager for X11. I&amp;#8217;ve only used it for a day, but I&amp;#8217;m addicted. I can&amp;#8217;t see myself going back to a non-tiling WM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I love not having to resize windows to put them next to each other.&lt;/li&gt;

&lt;li&gt;I love the extra screen space of not having window borders&lt;/li&gt;

&lt;li&gt;I love being able to run tons of programs on my small laptop screen, but still be able to see them all&lt;/li&gt;

&lt;li&gt;As a developer, I love that xmonad is small (just a thousand lines of Haskell), AND it&amp;#8217;s been run through a theorem prover!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, you probably don&amp;#8217;t want to run xmonad as a top-level window manager. If you run xmonad inside a gnome session, you get all the good stuff gnome usually does for free. Things like message notifications, wireless network connectivity, graphical multiple monitor support, password-management, volume control, printer support, power management, and device management. You could set up all that independently of gnome (and people do), but I don&amp;#8217;t consider it a good use of time.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how to run XMonad as a drop-in replacement for gnome&amp;#8217;s default window manager (Metacity):&lt;/p&gt;

&lt;p&gt;1) Install XMonad. Open a terminal and enter&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;sudo apt-get install xmonad
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;2) Configure XMonad to interact happily with gnome. Make a file &lt;code&gt;~/.xmonad/xmonad.hs&lt;/code&gt;, and put in it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='haskell'&gt;&lt;span class='kr'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;XMonad&lt;/span&gt;
&lt;span class='kr'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;XMonad.Config.Gnome&lt;/span&gt;

&lt;span class='nf'&gt;main&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;xmonad&lt;/span&gt; &lt;span class='n'&gt;gnomeConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Compile this config file by typing &lt;code&gt;xmonad --recompile&lt;/code&gt; at the terminal.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the crucial step most guides leave out.&lt;/em&gt; If you don&amp;#8217;t do this, xmonad will try and tile the two gnome panels, and then the nautilus desktop application will steal full the whole screen, and you won&amp;#8217;t be able to switch to your other programs, and you will swear a lot.&lt;/p&gt;

&lt;p&gt;3) Tell gnome to use xmonad instead of metacity. At the terminal, enter:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;gconftool-2 -s /desktop/gnome/session/required_components/windowmanager xmonad --type string
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And you&amp;#8217;re done! Logout, and log back in. The gnome-panel will happily coexist with the tiling window manager.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Log to the Error Console from a Firefox Extension</title>
   <link href="http://www.markhansen.co.nz/firefox-extension-console/" />
   <updated>2010-05-13T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/firefox-extension-console</id>
   <content type="html">&lt;p&gt;To log to the console from inside a firefox extension&amp;#8217;s javascript:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;Application&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Hello from my Firefox Extension!&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Get at the output from Tools -&amp;#38; Error Console.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re doing Firefox Extension development, you can&amp;#8217;t log to the Firebug console using &lt;code&gt;console.debug(object)&lt;/code&gt; like you&amp;#8217;re used to (&amp;#8216;console is not defined&amp;#8217;).&lt;/p&gt;

&lt;p&gt;At the time of writing, the ChromeBug XUL debugger (developed to debug firebug) is horribly buggy, and doesn&amp;#8217;t have a console. So it&amp;#8217;s either this, or alert() statements.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Bad Benchmarks</title>
   <link href="http://www.markhansen.co.nz/bad-benchmarks/" />
   <updated>2010-05-10T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/bad-benchmarks</id>
   <content type="html">&lt;p&gt;I saw someone ask today if &lt;a href='http://news.ycombinator.com/item?id=1334000'&gt;Chrome really is faster than Firefox&lt;/a&gt;. I&amp;#8217;ve always felt that chrome was &amp;#8216;snappier&amp;#8217; than Firefox, but I thought I&amp;#8217;d run a little (unscientific) test, to see if it really was.&lt;/p&gt;

&lt;p&gt;I compared Chrome and Firefox for startup time: from launch (from the terminal) till when the window appears and I click the close button.&lt;/p&gt;
&lt;pre&gt;
moon@Moon-Satellite ~&gt; &lt;b&gt;time google-chrome&lt;/b&gt;
0.56user 0.26system &lt;b&gt;0:03.03elapsed&lt;/b&gt; 27%CPU (0avgtext+0avgdata 246176maxresident)k
2304inputs+112outputs (3major+32511minor)pagefaults 0swaps

moon@Moon-Satellite ~&gt; &lt;b&gt;time firefox&lt;/b&gt;
1.80user 0.18system &lt;b&gt;0:09.21elapsed&lt;/b&gt; 21%CPU (0avgtext+0avgdata 206864maxresident)k
64648inputs+160outputs (233major+15989minor)pagefaults 0swaps
&lt;/pre&gt;
&lt;p&gt;Awesome! My little test had shown that Chrome started in 3 seconds, compared to Firefox&amp;#8217;s 9 seconds. That&amp;#8217;s well outside the margin of error I give for between me seeing the window is open and closing it. &lt;strong&gt;Hypothesis confirmed!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not so fast.&lt;/em&gt; I reran the tests, and the results were telling:&lt;/p&gt;
&lt;pre&gt;
moon@Moon-Satellite ~&gt; &lt;b&gt;time google-chrome&lt;/b&gt;
0.56user 0.21system &lt;b&gt;0:02.12elapsed&lt;/b&gt; 36%CPU (0avgtext+0avgdata 240384maxresident)k
0inputs+216outputs (0major+42590minor)pagefaults 0swaps
moon@Moon-Satellite ~&gt; &lt;b&gt;time firefox&lt;/b&gt;
1.57user 0.12system &lt;b&gt;0:02.70elapsed&lt;/b&gt; 62%CPU (0avgtext+0avgdata 199936maxresident)k
0inputs+112outputs (0major+15669minor)pagefaults 0swaps
&lt;/pre&gt;
&lt;p&gt;With a warm cache, Firefox manages to start in 2.70 seconds, and Chrome starts even faster, at 2.12 seconds. &lt;strong&gt;This is inconclusive&lt;/strong&gt; - the difference (half a second) is probably within the time it would take me to notice the window had popped up, and click the close button, telling &lt;code&gt;time&lt;/code&gt; to stop the clock.&lt;/p&gt;

&lt;p&gt;Of course, the first time you run firefox, the operating system has to go to the disc to get the firefox application, and all its configuration. The next time you run it, the operating system has a cache of all that data in RAM. RAM is just a straight read off a register chip, using only electricity, and electricity moves at almost the speed of light. You can only access the hard disk at the speed it spins (about the speed of a car). &lt;strong&gt;Big difference.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When benchmarking, beware of confirmation bias, and cache effects (even when the test is unscientific, and just for a bit of fun!).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Vim slow startup opening HTML</title>
   <link href="http://www.markhansen.co.nz/vim-slow-html/" />
   <updated>2010-05-09T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/vim-slow-html</id>
   <content type="html">&lt;p&gt;Editing files earlier, I&amp;#8217;d noticed it took &lt;em&gt;ages&lt;/em&gt; to load a file into vim. The screen would display the filename at the bottom, wait for about 10 seconds (pegging the CPU at 100%), and then display the file. This only happened for Markdown files, so I opened &lt;code&gt;markdown.vim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My first instinct was a runaway regular expression, backtracking all over the code&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='vim'&gt;&lt;span class='nb'&gt;syntax&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt;  htmlH1       &lt;span class='sr'&gt;/^.\+\n=\+$/&lt;/span&gt; contains&lt;span class='p'&gt;=&lt;/span&gt;@Spell
&lt;span class='nb'&gt;syntax&lt;/span&gt; &lt;span class='k'&gt;match&lt;/span&gt;  htmlH2       &lt;span class='sr'&gt;/^.\+\n-\+$/&lt;/span&gt; contains&lt;span class='p'&gt;=&lt;/span&gt;@Spell
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;These regular expressions match Markdown headings that look like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Heading 1
=========

Heading 2
---------&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I was concerned with the &lt;code&gt;.\+&lt;/code&gt; part of the regular expression. &lt;code&gt;.&lt;/code&gt; means &amp;#8216;match any character&amp;#8217; and &lt;code&gt;\+&lt;/code&gt; means match as many of the previous identifier as possible. &lt;code&gt;\+&lt;/code&gt; grabs as many characters as possible - it is a &lt;em&gt;greedy&lt;/em&gt; operator.&lt;/p&gt;

&lt;p&gt;If you tell Vim to match as many of &amp;#8216;any character&amp;#8217; as possible, it will first match the whole document, then have to backtrack through the whole thing to find a match for &lt;code&gt;\n=\+$&lt;/code&gt; (a newline containing only &lt;code&gt;=&lt;/code&gt; characters).&lt;/p&gt;

&lt;p&gt;Turns out this wasn&amp;#8217;t a problem, because in vimscript, the &amp;#8216;match any character&amp;#8217; doesn&amp;#8217;t match newlines, so the regex only goes to the end of the line. This is exactly the behaviour you want for the markdown parser. This wasn&amp;#8217;t the code that was pegging my CPU at 100%.&lt;/p&gt;

&lt;p&gt;Commenting out various lines of markdown.vim, I found the line causing the slow loads:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='vim'&gt;runtime&lt;span class='p'&gt;!&lt;/span&gt; &lt;span class='nb'&gt;syntax&lt;/span&gt;/html.&lt;span class='k'&gt;vim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There was a bug in the html syntax file that was causing this trouble. I tried commenting out the VBScript part of the html syntax file (who embeds VBScript in HTML any more?), and then the CSS section. Turning off CSS fixed the problem right away.&lt;/p&gt;

&lt;p&gt;The problem was this nifty little vimscript I downloaded a week ago to display CSS color strings like &amp;#8220;#e0f300&amp;#8221; in the color they represent: &lt;a href='http://www.vim.org/scripts/script.php?script_id=2150'&gt;css_color.vim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Removing this plugin bought me back to the happy world of sub-second startups. It&amp;#8217;s a shame, though, because &lt;code&gt;css_color.vim&lt;/code&gt; seems really useful to visualise colors as you&amp;#8217;re writing CSS. If someone could fix it up to not murder my startup time, that&amp;#8217;d be awesome! &lt;strong&gt;UPDATE 2011-10-02:&lt;/strong&gt; Someone&amp;#8217;s done just that - there&amp;#8217;s a &lt;a href='https://github.com/ap/vim-css-color'&gt;much, much faster version available&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lessons Learned at Reddit</title>
   <link href="http://www.markhansen.co.nz/reddit-lessons/" />
   <updated>2010-05-09T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/reddit-lessons</id>
   <content type="html">&lt;p&gt;I learned a lot about building scalable websites reading &lt;a href='http://carsonified.com/blog/dev/steve-huffman-on-lessons-learned-at-reddit/'&gt;Steve Huffman&amp;#8217;s &amp;#8216;Lessons Learned at Reddit&amp;#8217;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m super grateful they provided a transcript of the video, because Flash sucks big time on Linux. I tried to play it full screen, and the video would stutter, even though it had already loaded. I can&amp;#8217;t wait for the native rendering speeds promised by the &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Extreme Testing</title>
   <link href="http://www.markhansen.co.nz/sqlite-testing/" />
   <updated>2010-04-02T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/sqlite-testing</id>
   <content type="html">&lt;p&gt;I hear &lt;a href='http://news.ycombinator.com/item?id=879181'&gt;again&lt;/a&gt; and &lt;a href='http://www.reddit.com/r/programming/comments/26dyh/ask_reddit_whats_the_most_beautiful_piece_of/c26er9'&gt;again&lt;/a&gt; that SQLite&amp;#8217;s source code is among the best to learn from - high praise. But I had no idea how extreme their testing procedures are.&lt;/p&gt;

&lt;p&gt;I have never heard of a project being this extensively tested.&lt;/p&gt;

&lt;p&gt;From &lt;a href='http://www.sqlite.org/testing.html'&gt;How SQLite is Tested&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;SQLite has &lt;strong&gt;100% branch test coverage&lt;/strong&gt; on over &lt;strong&gt;67 thousand&lt;/strong&gt; source lines of code, with &lt;strong&gt;46 million&lt;/strong&gt; source lines of test cases.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s &lt;strong&gt;679 times as much&lt;/strong&gt; test code as production code. Wow.&lt;/p&gt;

&lt;p&gt;And it doesn&amp;#8217;t stop there. SQLite has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Out-of-memory tests&lt;/li&gt;

&lt;li&gt;I/O error tests&lt;/li&gt;

&lt;li&gt;Crash/Power loss tests&lt;/li&gt;

&lt;li&gt;Fuzz tests for invalid input&lt;/li&gt;

&lt;li&gt;Boundary value tests&lt;/li&gt;

&lt;li&gt;Malformed database tests&lt;/li&gt;

&lt;li&gt;Memory usage tests (valgrind)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The article dives deep into the challenges of such extensive testing. For example: How do you get 100% branch coverage when you have &amp;#8216;defensive code&amp;#8217; that should never be exercised? (the answer: leave the defensive code in, but remove it with the preprocessor before testing.)&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s well worth a read: &lt;a href='http://www.sqlite.org/testing.html'&gt;Testing in SQLite&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Updated node-XMLHttpRequest</title>
   <link href="http://www.markhansen.co.nz/node-xmlhttprequest/" />
   <updated>2010-03-29T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/node-xmlhttprequest</id>
   <content type="html">&lt;p&gt;I had an evening off from assignments, so I &lt;a href='http://github.com/mhansen/node-XMLHttpRequest/commits/master'&gt;updated node-XMLHttpRequest&lt;/a&gt; to reflect the extensive changes in the latest node.js API (0.1.33).&lt;/p&gt;

&lt;p&gt;&lt;a href='http://thedanexperiment.com/2009/10/04/emulating-xmlhttprequest-in-node-js/'&gt;node-XMLHttpRequest&lt;/a&gt; is a port of the browser&amp;#8217;s XMLHttpRequest object to node.js, to help ease porting of browser-based javascript to the node.js platform.&lt;/p&gt;

&lt;h3 id='race_conditions'&gt;Race Conditions&lt;/h3&gt;

&lt;p&gt;I thought I was going crazy when the HTTP Client silently failed to connect to the HTTP server. Eventually I found a race condition was set up in some test code between starting an HTTP server and starting the HTTP Client. It seems the http.createServer call is made asynchonously (like everything in node), and there&amp;#8217;s no event listener for when the server has binded to a port, so you just have to guess when it&amp;#8217;s ready to take your connection.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s easy enough, as a quick hack: good old &lt;code&gt;setTimeout&lt;/code&gt; delayed invocation of the client for 100 milliseconds.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;http&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;createServer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='cm'&gt;/*SNIP*/&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;listen&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;8000&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

&lt;span class='nx'&gt;setTimeout&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='cm'&gt;/* set up a client to connect to the above server */&lt;/span&gt;
&lt;span class='p'&gt;},&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='http_headers_are_caseinsensitive'&gt;HTTP Headers are case-insensitive&lt;/h3&gt;

&lt;p&gt;The old tests had an assertion, which was failing:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;headers&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Content-Type: text/plain\r\nContent-Length: 11\r\nConnection: close&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nx'&gt;assertEquals&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getAllResponseHeaders&lt;/span&gt;&lt;span class='p'&gt;());&lt;/span&gt;
&lt;span class='c1'&gt;// assertion failed: &lt;/span&gt;
&lt;span class='c1'&gt;// expected: &amp;#39;Content-Type: text/plain\r\nContent-Length: 11\r\nConnection: close&amp;#39;&lt;/span&gt;
&lt;span class='c1'&gt;// actual:   &amp;#39;content-type: text/plain\r\ncontent-length: 11\r\nconnection: close&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I did some research on &lt;a href='http://groups.google.com/group/nodejs/browse_thread/thread/d5aba0d09abcad86/8222513e6e4a3a27'&gt;why node.js lowercases header names&lt;/a&gt; and was surprised to find that the &lt;a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2'&gt;RFC 2616 defines HTTP Headers to be case-insensitive&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;HTTP agents are free to manipulate the case of headers, so agents shouldn&amp;#8217;t depend on the header having a certain case. Oops.&lt;/p&gt;

&lt;p&gt;So why does node.js automatically lowercase these headers, instead of leaving them unchanged? Let&amp;#8217;s look at these options.&lt;/p&gt;

&lt;h4 id='pass_on_the_headers_to_the_user_of_the_code_unchanged'&gt;Pass on the headers to the user of the code, unchanged.&lt;/h4&gt;

&lt;p&gt;To be RFC 2616h compliant, the programmer would have to do a case-insensitive match on the headers. &lt;a href='http://groups.google.com/group/nodejs/msg/0c3e638f53d0a859'&gt;Not trivial when the headers are given as keys to an object&lt;/a&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;contentType&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; 
&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;header&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;req&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='c1'&gt;//case insensitive match&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;header&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/Content-Type/i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
            &lt;span class='nx'&gt;contentType&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;req&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;header&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt; 
            &lt;span class='k'&gt;break&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt; 
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='enforce_strict_lowercase_or_uppercase_on_headers'&gt;Enforce strict lowercase or uppercase on headers.&lt;/h4&gt;

&lt;p&gt;Clients can access the headers with:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;contentType&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;request&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Put like that, it&amp;#8217;s kind of a no-brainer. I&amp;#8217;m grateful to node.js for helping me make my code not only compliant, but also liberal in what it accepts. And I don&amp;#8217;t even have to lift a finger. Awesome!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Trust the Profiler</title>
   <link href="http://www.markhansen.co.nz/profiling/" />
   <updated>2010-03-27T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/profiling</id>
   <content type="html">&lt;p&gt;I was totally wrong.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been working on an LZW data compressor for my Algorithms paper with a partner.&lt;/p&gt;

&lt;p&gt;We thought we were being smart about it - we designed our data structures to use a &lt;a href='http://en.wikipedia.org/wiki/Trie'&gt;multiway trie&lt;/a&gt; on the compressor, and a simple lookup table on the decompresser. Runtime should be strictly O(n) to compress any n-sized file.&lt;/p&gt;

&lt;p&gt;Our code worked wonderfully on small files, but as soon as we turned it to the 5MB &lt;a href='http://en.wikipedia.org/wiki/Brown_Corpus'&gt;Brown Corpus&lt;/a&gt;, after a few minutes it had only chewed through 20% of the file, and it was getting slower as it went. Definitely not O(n) behavior.&lt;/p&gt;

&lt;p&gt;Every iteration, we were careful to only make one change to the data structure, and one move in the data structure.&lt;/p&gt;

&lt;p&gt;My partner thought that we should profile the program to find out where the bad behavior is, but I didn&amp;#8217;t think that&amp;#8217;d be necessary - we&amp;#8217;d be able to find the flaw pretty quickly just by looking through the code, right? - there were only a few accesses to our data structures. We &lt;em&gt;must&lt;/em&gt; have been doing something wrong there.&lt;/p&gt;

&lt;p&gt;Well, I tried looking, and he profiled the program. He &lt;em&gt;easily&lt;/em&gt; got the answer in seconds, and it wasn&amp;#8217;t something obvious just from looking at the code, at all.&lt;/p&gt;

&lt;p&gt;By running &lt;code&gt;java -Xprof Compressor &amp;lt; brown.txt&lt;/code&gt; the built-in Java profiler was invoked, which samples that stack every 10ms, to see which function it&amp;#8217;s in. He found over 90% of computation time was spent inside &lt;code&gt;Vector.toString()&lt;/code&gt;&amp;#8230;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kt'&gt;boolean&lt;/span&gt; &lt;span class='n'&gt;DEBUG&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;false&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;private&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;log&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;DEBUG&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;err&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
    &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;

&lt;span class='cm'&gt;/* ...SNIP... */&lt;/span&gt;
&lt;span class='n'&gt;log&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;myVector&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;toString&lt;/span&gt;&lt;span class='o'&gt;());&lt;/span&gt; &lt;span class='c1'&gt;//on every iteration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;However, even though debugging was disabled, java was still evaluating &lt;code&gt;myVector.toString()&lt;/code&gt; &lt;em&gt;every iteration&lt;/em&gt;. Of course, &lt;code&gt;toString()&lt;/code&gt; has to iterate through every value in our data structure. All this computation was occurring, even though &lt;code&gt;log()&lt;/code&gt; was effectively a no-op.&lt;/p&gt;

&lt;p&gt;So, now I&amp;#8217;m sold on two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Profilers.&lt;/em&gt; Especially java&amp;#8217;s builtin profiler - could it be easier to profile your code? I don&amp;#8217;t think so. Just add the &lt;code&gt;-Xprof&lt;/code&gt; flag.&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&lt;a href='http://en.wikipedia.org/wiki/Lazy_evaluation'&gt;Lazy Evaluation&lt;/a&gt;.&lt;/em&gt; Why compute data you&amp;#8217;re not going to do anything with?&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Rainy Nights</title>
   <link href="http://www.markhansen.co.nz/rainy-nights/" />
   <updated>2010-02-27T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/rainy-nights</id>
   <content type="html">&lt;p&gt;Love the sound of a rainy night? I know I do! Well, &lt;a href='http://rainymood.com/'&gt;there&amp;#8217;s a site for that&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The best way to stay cool</title>
   <link href="http://www.markhansen.co.nz/cool/" />
   <updated>2010-02-26T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/cool</id>
   <content type="html">&lt;p&gt;We were partying at a dance club, it was busy, and I was overheating. So I asked for some water - but what they gave me was 90% ice, topped off with water. It did an awesome job at cooling me down.&lt;/p&gt;

&lt;p&gt;Later on, I got thinking - &lt;strong&gt;How much better is ice at cooling you down than water?&lt;/strong&gt; (Hey, I was a chemistry student in a past life).&lt;/p&gt;

&lt;p&gt;While water does an admirable job cooling you down at a dance party, clearly ice is better. But how much better?&lt;/p&gt;

&lt;p&gt;To make this fair on water, we&amp;#8217;ll skew our test a bit in water&amp;#8217;s favor, comparing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the coldest possible liquid H&lt;sub&gt;2&lt;/sub&gt;O (water at 0°C)&lt;/li&gt;

&lt;li&gt;to the warmest possible solid H&lt;sub&gt;2&lt;/sub&gt;O (ice at 0°C)&lt;/li&gt;

&lt;li&gt;for cooling down a hot person (slightly over 37°C)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='water'&gt;Water&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://www.flickr.com/photos/mattandkim/3969185159/'&gt;&lt;img alt='Glass of water' src='/images/water.jpg' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Water cools you down in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Water is usually less than 37°C when you drink it. Once it is inside your body, its temperature rises.&lt;/p&gt;

&lt;p&gt;Temperature rises need energy, and the energy is taken from your body heat, cooling you down.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;You can sweat the water out, where it vaporises (turns to gas). Vaporisation requires energy, some of which is taken from your body heat, cooling you down.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As anyone who&amp;#8217;s ever been to a concert can testify, sweating is useless when there&amp;#8217;s no wind, and humidity is at 100% (e.g. in a dance club). So we can ignore its effects here.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.wolframalpha.com/input/?i=heat+capacity+of+water&amp;amp;a=*C.heat+capacity-_*ChemicalProperty.dflt-&amp;amp;a=*DPClash.ChemicalP.heat+capacity-_*SpecificHeatCapacity-'&gt;It takes &lt;strong&gt;4.18J&lt;/strong&gt; to heat one gram of water by 1°C&lt;/a&gt;. Ingesting water at 0°C, you will raise its temperature by 37° to body temperature.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;4.18J/g x 37° = 155J/g&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The energy to heat up the water comes from your body heat, so you will lose &lt;strong&gt;155J&lt;/strong&gt; per gram of water you drink.&lt;/p&gt;

&lt;h2 id='ice'&gt;Ice&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://www.flickr.com/photos/stevendepolo/3072821281/'&gt;&lt;img alt='Ice cubes' src='/images/ice.jpg' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ice melts, forming water (obviously). It takes a lot of energy to melt the ice - you have to partially break hydrogen bonds - one of the strongest bonds in chemistry.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.wolframalpha.com/input/?i=enthalpy+of+fusion+of+water&amp;amp;a=*DPClash.ChemicalP.enthalpy+of+fusion-_*SpecificFusionHeat-'&gt;It takes &lt;strong&gt;334J&lt;/strong&gt; to melt one gram of ice&lt;/a&gt;. That&amp;#8217;s almost twice the energy you lose in heating that same gram of water from 0°C to 37°C!&lt;/p&gt;

&lt;p&gt;And, once that gram of ice is melted, you&amp;#8217;re left with a gram of water at 0°. Which, as we&amp;#8217;ve established, cools you down by &lt;strong&gt;155J&lt;/strong&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;melting energy + heating energy = total
334J/g         + 155J/g         = 489J/g&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='conclusion'&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Drinking one gram of 0°C water will cool you down by &lt;strong&gt;155J&lt;/strong&gt;. Drinking one gram of ice at 0°C will cool you down by &lt;strong&gt;489J&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;at minimum&lt;/strong&gt; ice cools you down &lt;strong&gt;over three times as well&lt;/strong&gt; as water. If the ice is colder, or the water is warmer, ice does even better. Awesome!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hofstadter on Intelligence</title>
   <link href="http://www.markhansen.co.nz/intelligence/" />
   <updated>2010-02-24T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/intelligence</id>
   <content type="html">&lt;p&gt;Reading GEB today, I came across this nice definition of intelligence I had to share:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No one knows where the borderline between non-intelligent behaviour and intelligent behaviour lies; in fact, to suggest that a sharp borderline exists is probably silly. But essential abilities for intelligence are certainly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to respond to sitations very flexibly;&lt;/li&gt;

&lt;li&gt;to take advantage of fortuitious circumstances;&lt;/li&gt;

&lt;li&gt;to make sense out of ambiguous or contradictory messages;&lt;/li&gt;

&lt;li&gt;to recognize the relative importance of different elements of a situation;&lt;/li&gt;

&lt;li&gt;to find similarities between situations despite differences which may separate them;&lt;/li&gt;

&lt;li&gt;to draw distinctions between situations despite similarities which may link them;&lt;/li&gt;

&lt;li&gt;to synthesize new concepts by taking old concepts and putting them together in new ways;&lt;/li&gt;

&lt;li&gt;to come up with ideas which are novel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;#8211; Douglas R. Hofstadter, in &lt;a href='http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach'&gt;Godel, Escher, Bach: An Eternal Golden Braid&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ruby from Java</title>
   <link href="http://www.markhansen.co.nz/java-to-ruby/" />
   <updated>2010-02-23T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/java-to-ruby</id>
   <content type="html">&lt;p&gt;&lt;a href='http://onestepback.org/articles/10things/index.html'&gt;10 Things Every Java Programmer Should Know About Ruby (2006)&lt;/a&gt;, by Jim Weirich.&lt;/p&gt;

&lt;p&gt;This is a &lt;em&gt;concise&lt;/em&gt; guide to the major differences between Ruby and Java (or java-like languages, e.g. C#). Reading it, I finally feel like I fully understand mixins and messages. The real-life examples for everything helped a lot.&lt;/p&gt;

&lt;p&gt;I can recommend these slides for anyone coming from a Java or C# background who wants to learn about Ruby.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Selling Static Analysis</title>
   <link href="http://www.markhansen.co.nz/coverity/" />
   <updated>2010-02-20T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/coverity</id>
   <content type="html">&lt;p&gt;The people behind &lt;a href='http://www.coverity.com'&gt;Coverity&lt;/a&gt;, a commercial static analysis bugfinding tool, have &lt;a href='http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext/'&gt;shared their experiences&lt;/a&gt; in selling business software. It starts off a little slow, but it&amp;#8217;s a fascinating read, exposing many counter-intuitive problems in the way software is developed:&lt;/p&gt;

&lt;p&gt;Some managers refused to upgrade to the latest version of the bugfinding tool. That sounds like a no-brainer to me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you get the latest version&lt;/li&gt;

&lt;li&gt;you get a better analysis of your code&lt;/li&gt;

&lt;li&gt;you find more bugs&lt;/li&gt;

&lt;li&gt;you fix them before your customers find them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But if you&amp;#8217;re a manager and your bonus depends on the bug number going down, the last thing you want is a new version of the tool to push bug numbers back up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At company X, version 2.4 of the tool found approximately 2,400 errors, and over time the company fixed about 1,200 of them. Then it upgraded to version 3.6. Suddenly there were 3,600 errors. The manager was furious for two reasons: One, we &amp;#8220;undid&amp;#8221; all the work his people had done, and two, how could we have missed them the first time?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gah!&lt;/p&gt;

&lt;p&gt;The article&amp;#8217;s a great read. &lt;a href='http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext/'&gt;Check it out&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Installing JSON.vim</title>
   <link href="http://www.markhansen.co.nz/vim-json/" />
   <updated>2010-02-18T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/vim-json</id>
   <content type="html">&lt;ol&gt;
&lt;li&gt;Download &lt;a href='http://www.vim.org/scripts/script.php?script_id=1945'&gt;Json.vim&lt;/a&gt; to &lt;code&gt;~/.vim/syntax/json.vim&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Make a new file &lt;code&gt;~/.vim/ftdetect/json.vim&lt;/code&gt; and write in it:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='vim'&gt;au &lt;span class='nb'&gt;BufRead&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='nb'&gt;BufNewFile&lt;/span&gt; *.json &lt;span class='k'&gt;set&lt;/span&gt; &lt;span class='k'&gt;filetype&lt;/span&gt;&lt;span class='p'&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='how_does_this_work'&gt;How does this work?&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;When you put a file in &lt;code&gt;~/.vim/syntax/{name}.vim&lt;/code&gt;, that syntax highlighting file will be loaded whenever the &lt;code&gt;filetype&lt;/code&gt; variable is set to &lt;code&gt;{name}&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;The second step sets &lt;code&gt;filetype=json&lt;/code&gt; whenever you load a file ending with &lt;code&gt;.json&lt;/code&gt;, triggering the syntax highlighting.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href='http://www.vim.org/scripts/script.php?script_id=1945'&gt;JSON.vim&lt;/a&gt; is a syntax highlighter for &lt;a href='http://json.org'&gt;JSON&lt;/a&gt; code, but the install instructions are a little light on detail.&lt;/p&gt;

&lt;p&gt;Other &lt;a href='http://blog.graphtech.co.il/editing-json-files-in-vim/'&gt;blog&lt;/a&gt; &lt;a href='http://bradmontgomery.blogspot.com/2010/01/add-json-syntax-highlighting-in-vim-on.html'&gt;posts&lt;/a&gt; tell you to explicitly source JSON.vim from some explicit path. This will work for one computer, but will fail if you like to use your vimfiles in different directories on more than one computer. (e.g. my vimfiles are in ~/.vim/ on unix, and ~/vimfiles on windows)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NZ Phone Numbers</title>
   <link href="http://www.markhansen.co.nz/nz-phone-regex/" />
   <updated>2010-02-17T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/nz-phone-regex</id>
   <content type="html">&lt;p&gt;Setting up a VoIP router today, I came across an interesting setting: &amp;#8216;Dial Plan 1&amp;#8217;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(*xx|#xx|1xx|082210S0|[2-9]xxxxxx|0[3469]xxxxxxxS0|0800xxxxxxS0|00[1-9]x.S3|0[12578]x.S3|0900xxxxxxS0)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That looks suspiciously like a regular expression, matching New Zealand phone numbers! Cool! Let&amp;#8217;s analyze it. I love a puzzle.&lt;/p&gt;

&lt;h2 id='quick_regex_primer'&gt;Quick Regex Primer&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[abc123]&lt;/code&gt; matches any one of the symbols inside the bracket. Called a &amp;#8216;character class&amp;#8217;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;[1-9]&lt;/code&gt; is the same as &lt;code&gt;[123456789]&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;(pattern1|pattern2|pattern3)&lt;/code&gt; is the basic OR of regular expressions: match &lt;code&gt;pattern1&lt;/code&gt; OR &lt;code&gt;pattern2&lt;/code&gt; OR &lt;code&gt;pattern3&lt;/code&gt;. So in this expression, it looks like there are about 10 different types of general phone numbers.&lt;/li&gt;

&lt;li&gt;In this regex flavor, it looks like &lt;code&gt;x&lt;/code&gt; is used as a stand-in for any number: a shorter way of saying &lt;code&gt;[0-9]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='splitting_the_regex'&gt;Splitting the Regex&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*xx&lt;/code&gt;&lt;br /&gt;Usually, &lt;code&gt;*&lt;/code&gt; in a regular expression means &amp;#8220;match any number of the previous token&amp;#8221;. Here, &lt;code&gt;*&lt;/code&gt; is the first token, so it can&amp;#8217;t mean that. I&amp;#8217;m guessing that it literally means the &lt;code&gt;*&lt;/code&gt; button on the phone, followed by two numbers.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;#xx&lt;/code&gt;&lt;br /&gt;Hash, followed by two numbers.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;1xx&lt;/code&gt;&lt;br /&gt;One, followed by two numbers. Example: &lt;em&gt;111&lt;/em&gt; (emergency services)&lt;/li&gt;

&lt;li&gt;&lt;code&gt;082210S0&lt;/code&gt;&lt;br /&gt;Probably my ISP&amp;#8217;s voicemail service. I wouldn&amp;#8217;t know: I forgot the PIN number shortly after signing up and haven&amp;#8217;t used voicemail since :)&lt;/li&gt;

&lt;li&gt;&lt;code&gt;[2-9]xxxxxx&lt;/code&gt;&lt;br /&gt;In New Zealand, a local number is dialed with 7 numbers. I never knew that they weren&amp;#8217;t allowed to start with a 1.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;0[3469]xxxxxxxS0&lt;/code&gt;&lt;br /&gt;&lt;code&gt;0&lt;/code&gt; is the national access code. If a number starts with &lt;code&gt;03&lt;/code&gt;, &lt;code&gt;04&lt;/code&gt;, &lt;code&gt;06&lt;/code&gt;, or &lt;code&gt;09&lt;/code&gt;, it is a national call. Notably absent is &lt;code&gt;07&lt;/code&gt; the area code for where I live.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;0800xxxxxxS0&lt;/code&gt;&lt;br /&gt;&lt;code&gt;0800&lt;/code&gt; numbers are national freecall hotlines.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;00[1-9]x.S3&lt;/code&gt;&lt;br /&gt;&lt;code&gt;00&lt;/code&gt; is the international access code. It&amp;#8217;s strange that there&amp;#8217;s only one &lt;code&gt;x&lt;/code&gt; here, as there will probably be many more numbers after the country code. e.g. to call the US, you need to dial &lt;code&gt;00&lt;/code&gt; for international, &lt;code&gt;1&lt;/code&gt; for US, then the seven-digit US phone number.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;0[12578]x.S3&lt;/code&gt;&lt;br /&gt;Aha! Here are the other area codes. These are invalid numbers - these area codes don&amp;#8217;t exist in New Zealand, except for &lt;code&gt;07&lt;/code&gt; - my area code, which is an error if you use it for a local call.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;0900xxxxxxS0&lt;/code&gt;&lt;br /&gt;0900 numbers: They charge you by the minute to call them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='unsolved_mysteries'&gt;Unsolved Mysteries&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is the purpose of this regex?&lt;/li&gt;

&lt;li&gt;&lt;code&gt;S0&lt;/code&gt; and &lt;code&gt;S3&lt;/code&gt; suffixes at the end some regexes. What do they mean?&lt;/li&gt;

&lt;li&gt;What do &lt;code&gt;.&lt;/code&gt; dots mean?&lt;/li&gt;

&lt;li&gt;Why is there nothing distinguishing the valid numbers from the invalid &lt;code&gt;0[12578]x.S3]&lt;/code&gt; form?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This format is probably documented somewhere. This regex was found on a &lt;em&gt;Linksys AG310 ADSL2+ Gateway with VoIP&lt;/em&gt;. But I know from experience that searching through a supplier&amp;#8217;s website for documentation is usually a horrible experience, so I think I&amp;#8217;ll let these mysteries lie. :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Git inside Git</title>
   <link href="http://www.markhansen.co.nz/git-repo-inside-git/" />
   <updated>2010-02-11T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/git-repo-inside-git</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;UPDATE 2011:&lt;/strong&gt; I don&amp;#8217;t use this technique any more, because Git submodules kinda suck. Instead, I use &lt;a href='http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb'&gt;felixge&amp;#8217;s technique&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How do you keep another Git repository inside a folder that&amp;#8217;s already under version control with Git? Why would you do this?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I keep my vim config files under revision control, and I tried cloning other people&amp;#8217;s vim modules from github into subdirectories of my repository.&lt;/li&gt;

&lt;li&gt;I use &lt;a href='http://documentcloud.github.com/underscore/'&gt;underscore.js&lt;/a&gt; inside some of my javascript projects. Both are kept in git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you &lt;code&gt;git clone&lt;/code&gt;, git will happily comply and clone the repository into your folder, but you won&amp;#8217;t be able to add the &lt;code&gt;.git&lt;/code&gt; folder into revision control. If you try to &lt;code&gt;git add subrepository/.git&lt;/code&gt;, your request will be ignored, as if the .git folder doesn&amp;#8217;t exist at all:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;git add subrepository/.git
fatal: pathspec &lt;span class='s1'&gt;&amp;#39;subrepository.git&amp;#39;&lt;/span&gt; did not match any files
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And that&amp;#8217;s just as well - keeping track of a repository&amp;#8217;s history inside another repository would be horribly wasteful. And every time the subrepository updates, the parent repository will need to update both the working directory files and the subrepository history files, complicating the diffs. And it&amp;#8217;s just not necessary: git has a great way of keeping git repositories inside git.&lt;/p&gt;

&lt;h3 id='submodules'&gt;Submodules&lt;/h3&gt;

&lt;p&gt;Submodules are a way of importing code from other git repositories into your source tree, and keeping them up to date after they are imported.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nb'&gt;cd &lt;/span&gt;my_git_repo_root
git submodule add &amp;lt;remote repository&amp;gt; &amp;lt;&lt;span class='nb'&gt;local &lt;/span&gt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will checkout the remote repository into the local path, and records the remote repository in a &lt;code&gt;.gitmodules&lt;/code&gt; at the root of your repo.&lt;/p&gt;

&lt;p&gt;Then, later on, if a new version of a submodule is released, you can update your copy with&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;git submodule update
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;s the basics. For more info:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://book.git-scm.com/5_submodules.html'&gt;Submodules in the Git Book&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html'&gt;git-submodule(1) manpage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Don't debug with JSON.Stringify</title>
   <link href="http://www.markhansen.co.nz/inspecting-with-json-stringify/" />
   <updated>2010-02-10T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/inspecting-with-json-stringify</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been having some problems using JSON.Stringify to inspect objects while debugging inside &lt;a href='http://nodejs.org'&gt;node.js&lt;/a&gt;. It seems like a great choice:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='s2'&gt;&amp;quot;prop1&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;value1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
    &lt;span class='s2'&gt;&amp;quot;prop2&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;JSON&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stringify&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;obj&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
&lt;span class='c1'&gt;//prints: {&amp;quot;prop1&amp;quot;:&amp;quot;value1&amp;quot;,&amp;quot;prop2&amp;quot;:5}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But there are gotchas:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;infinity&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='o'&gt;/&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;func&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{};&lt;/span&gt;
&lt;span class='nx'&gt;func&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;innerproperty&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;prop1&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;func&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;prop2&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;prop3&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nx'&gt;infinity&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;JSON&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stringify&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;obj&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='c1'&gt;//prints {&amp;quot;prop3&amp;quot;:null}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Oh no! JSON.Stringify has&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ignored &lt;code&gt;prop1&lt;/code&gt;, a function&lt;/li&gt;

&lt;li&gt;ignored &lt;code&gt;func.innerproperty&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;ignored &lt;code&gt;prop2&lt;/code&gt;, an undefined value&lt;/li&gt;

&lt;li&gt;replaced &lt;code&gt;prop3&lt;/code&gt;&amp;#8217;s &lt;code&gt;Infinity&lt;/code&gt; with &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yikes! This is because JSON, being a pure data interchange format, has no notation for functions. Or undefined values. And it replaces nonfinite numbers with &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In node.js, there&amp;#8217;s a dedicated function for stringifying objects for debuggings: &lt;code&gt;sys.inspect(object)&lt;/code&gt;. See the &lt;a href='http://nodejs.org/api.html#_system_module'&gt;API docs&lt;/a&gt;. This fares somewhat better for the last example, outputting:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
 &amp;quot;prop1&amp;quot;: [Function],
 &amp;quot;prop2&amp;quot;: undefined,
 &amp;quot;prop3&amp;quot;: Infinity
}&lt;/code&gt;&lt;/pre&gt;
&lt;del&gt;However, note that it doesn't check for function properties.
`prop1.innerproperty` is ignored.&lt;/del&gt;
&lt;p&gt;&lt;em&gt;EDIT&lt;/em&gt;: I opened an &lt;a href='http://github.com/ry/node/issues#issue/61'&gt;issue&lt;/a&gt;, and it was fixed in less than a day. Functions with properties are now listed too. Thanks, &lt;a href='http://github.com/creationix'&gt;creationix&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;This is pretty important, because it&amp;#8217;s very common to use functions as property holders in popular javascript libraries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt; uses &lt;code&gt;$&lt;/code&gt; both as a selector function, and a library object&lt;/li&gt;

&lt;li&gt;&lt;a href='http://documentcloud.github.com/underscore/'&gt;underscore.js&lt;/a&gt; uses &lt;code&gt;_&lt;/code&gt; as a wrapper function, and a library object&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Benchmark your DNS!</title>
   <link href="http://www.markhansen.co.nz/namebench/" />
   <updated>2010-02-08T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/namebench</id>
   <content type="html">&lt;p&gt;Every time you browse to a website, your computer needs to translate the human-readable URL (&lt;code&gt;www.google.com&lt;/code&gt;) into an IP (&lt;code&gt;66.102.7.103&lt;/code&gt;). It does this by asking your DNS servers. The speed of your DNS server can really impact the speed of your internet browsing.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a lot of choices for DNS servers. Chances are you&amp;#8217;re just using your ISP&amp;#8217;s one, and this may not be the fastest. I was using &lt;a href='http://xnet.co.nz'&gt;my ISP&lt;/a&gt;&amp;#8217;s DNS servers, and it turns out that on average &lt;a href='http://xtra.co.nz'&gt;another ISP&lt;/a&gt;&amp;#8217;s DNS servers were over twice as fast - from 258ms down to 112ms!&lt;/p&gt;

&lt;p&gt;You can benchmark your DNS servers with &lt;a href='http://code.google.com/p/namebench/'&gt;namebench&lt;/a&gt;, a free tool for Windows, Mac, and UNIX. Namebench is smart - it pulls data from your browser history to ensure your DNS is optimised for the sites you frequent. Namebench checks the best DNS servers in your region, as well as global services like Google Public DNS, OpenDNS, and UltraDNS. Namebench even checks for incorrect results from DNS Servers!&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m very impressed with how simple, smart and effective namebench is. Kudos to the developers! Thanks for the 50% reduction in DNS wait times.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mouse Hiding in MinTTY</title>
   <link href="http://www.markhansen.co.nz/mintty-hidden-mouse/" />
   <updated>2010-02-03T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/mintty-hidden-mouse</id>
   <content type="html">&lt;p&gt;I love &lt;a href='http://code.google.com/p/mintty/'&gt;MinTTY&lt;/a&gt; - it&amp;#8217;s the best terminal emulator I know of for Windows. It&amp;#8217;s so much better than the default cmd.exe window that Cygwin uses by default. You can&amp;#8217;t resize &lt;code&gt;cmd.exe&lt;/code&gt;, and has almost no scrollback.&lt;/p&gt;

&lt;p&gt;But I&amp;#8217;ve been having an intermittent problem with it - my mouse cursor keeps disappearing. I move my mouse, hoping to find it, but it&amp;#8217;s invisible until I click somewhere (and I can&amp;#8217;t see where I&amp;#8217;m clicking). It&amp;#8217;s panicing!&lt;/p&gt;

&lt;p&gt;Today I did some tests - the problem occurs when you move the mouse outside the MinTTY window, and then type. The mouse disappears, and doesn&amp;#8217;t reappear until it moves back into the MinTTY window.&lt;/p&gt;

&lt;p&gt;So I looked through the MinTTY source code to see what&amp;#8217;s causing this. That&amp;#8217;s easy enough. It&amp;#8217;s open source, and hosted at Google Code.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;svn checkout http://mintty.googlecode.com/svn/trunk/ mintty-read-only
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The source code is rather small, for a program written in C. With a little help from &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;ctags&lt;/code&gt; it was easy to find the bit concerning mouse input - in &lt;a href='http://code.google.com/p/mintty/source/browse/trunk/wininput.c'&gt;wininput.c&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The mouse is hidden whenever a keypress notification arrives. Keypress notifications arrive when the mouse is both inside and outisde the window. The mouse is shown whenever a mouse click/release/move notification arrives. Mouse notifications are only delivered when the mouse is inside the window area.&lt;/p&gt;

&lt;p&gt;So it seems the mouse can be hidden by a keypress event while it is outside the window, but it won&amp;#8217;t reappear, even if you move the mouse, until it reenters the window. Or you click onto another program.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a simple solution: check if the mouse is inside the window before hiding it. I looked up a few Windows API calls, found the ones I needed were &lt;code&gt;GetWindowRect()&lt;/code&gt; and &lt;code&gt;GetCursorPos()&lt;/code&gt;. I made the change, recompiled, tested, and it works!&lt;/p&gt;

&lt;p&gt;I checked the edge cases (literal edge cases - the four window edges), and it even works there: I was worried that moving from just inside the window to outside wouldn&amp;#8217;t send a mouse-move notification to the window, but happily it does.&lt;/p&gt;

&lt;p&gt;So, here it is - my first submitted patch to an open-source project. It&amp;#8217;s not much, but it&amp;#8217;s a start. :)&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='k'&gt;static&lt;/span&gt; &lt;span class='n'&gt;bool&lt;/span&gt;
&lt;span class='nf'&gt;mouse_inside_window&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;RECT&lt;/span&gt; &lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;POINT&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;GetWindowRect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;wnd&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;GetCursorPos&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt;
        &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;left&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;right&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;top&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;m&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;bottom&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kt'&gt;void&lt;/span&gt;
&lt;span class='nf'&gt;hide_mouse&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;mouse_showing&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;mouse_inside_window&lt;/span&gt;&lt;span class='p'&gt;())&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;ShowCursor&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;false&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;mouse_showing&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;false&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: The MinTTY maintainer Andy Koppe was &lt;a href='http://code.google.com/p/mintty/issues/detail?id=160'&gt;totally awesome helping with my problem&lt;/a&gt;, but he can&amp;#8217;t reproduce the problem at his end, and after I restarted my computer I can&amp;#8217;t reproduce it either.&lt;/p&gt;

&lt;p&gt;However, the problem has been troubling me for a few months, so I&amp;#8217;m sure it will be back. And when it does, I&amp;#8217;ll be ready. ;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Git in Color</title>
   <link href="http://www.markhansen.co.nz/color-git/" />
   <updated>2010-02-01T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/color-git</id>
   <content type="html">&lt;p&gt;By default, git doesn&amp;#8217;t use color. However, you can enable color for interactive use:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;git config --global --add color.ui &lt;span class='nb'&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This adds a line to your ~/.gitconfig file, enabling colors output for all git operations on all repositories.&lt;/p&gt;

&lt;p&gt;Awesome! Now &lt;code&gt;git-diff&lt;/code&gt; will shine in radiant reds and greens, and it&amp;#8217;ll be oh-so-easy to see what&amp;#8217;s changed. &lt;code&gt;git-branch&lt;/code&gt; will show your current branch in green, &lt;code&gt;git-status&lt;/code&gt; will show added files in green and deleted files in red.&lt;/p&gt;

&lt;p&gt;And git&amp;#8217;s smart enough to check if the output is going to the terminal or to a pipe, where color codes could break things. Git only sends color output to the terminal, where your eyes can enjoy it. I can&amp;#8217;t see any reason &lt;em&gt;not&lt;/em&gt; to enable color in git. Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Optional parameters in Javascript</title>
   <link href="http://www.markhansen.co.nz/javascript-optional-parameters/" />
   <updated>2010-01-19T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/javascript-optional-parameters</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been reading a &lt;a href='http://github.com/creationix/node-router/blob/master/node-router.js'&gt;lot&lt;/a&gt; &lt;a href='http://github.com/ry/node_chat/blob/master/server.js'&gt;of&lt;/a&gt; &lt;a href='http://github.com/caludio/node.xmlrpc-c'&gt;JavaScript&lt;/a&gt; &lt;a href='http://github.com/driverdan/node-XMLHttpRequest/blob/master/XMLHttpRequest.js'&gt;code&lt;/a&gt; lately, and it&amp;#8217;s been a joy. I&amp;#8217;m picking up on some common JavaScript idioms too, and I thought I&amp;#8217;d share.&lt;/p&gt;

&lt;h3 id='introduction_to_optional_parameters'&gt;Introduction to Optional Parameters&lt;/h3&gt;

&lt;p&gt;Optional parameters are a nice language feature - function parameters that are given default values if not used when calling a function. Optional parameters are great for simplifying code, and hiding advanced but not-often-used functionality. If 90% of the time you&amp;#8217;re calling a function using the same values for some parameters, you should look into making those parameters optional to avoid &lt;a href='http://en.wikipedia.org/wiki/DRY'&gt;Repeating Yourself&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Compare this C# code for connecting to a server, first without optional parameters:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; 
    &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;

&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
    &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='m'&gt;80&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt; 

&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;port&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
    &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;port&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;HTTP&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;

&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;port&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;method&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='p'&gt;...&lt;/span&gt; 
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, with the new C# 4.0 optional parameters, things are a lot simpler:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='csharp'&gt;&lt;span class='k'&gt;public&lt;/span&gt; &lt;span class='k'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;hostname&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
                    &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;port&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='m'&gt;80&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='n'&gt;method&lt;/span&gt; &lt;span class='p'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;HTTP&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;...&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='method_1_undefined_arguments'&gt;Method 1: Undefined arguments&lt;/h4&gt;

&lt;p&gt;At first glance, javascript has nothing like this available. However, javascript lets you call functions omitting some parameters, filling in the other parameters with the value &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;www.google.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
     &lt;span class='c1'&gt;// inside the function, &lt;/span&gt;
     &lt;span class='c1'&gt;// hostname === &amp;quot;www.google.com&amp;quot;, &lt;/span&gt;
     &lt;span class='c1'&gt;// port === undefined,&lt;/span&gt;
     &lt;span class='c1'&gt;// method === undefined &lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s easy to check if a value is &lt;code&gt;undefined&lt;/code&gt; and fill it in with a default parameter if it is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;hostname&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;hostname&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;80&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;HTTP&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;However, there&amp;#8217;s a prettier shortcut:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;hostname&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;hostname&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='mi'&gt;80&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The short-circuit OR operator &lt;code&gt;||&lt;/code&gt; returns the left side if the left argument is truthy (evaluates to &lt;code&gt;true&lt;/code&gt; in conditionals), otherwise it checks if the right argument is truthy, returning it. We can use this shortcut because &lt;code&gt;undefined&lt;/code&gt; is falsy: in conditionals, &lt;code&gt;undefined&lt;/code&gt; evaluates to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This shortcut approach is a very common idiom, but it does have a disadvantage: You can&amp;#8217;t use for any argument that could accept a falsy value: &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;undefined&lt;/code&gt;, the empty string &lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt;, and &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;||&lt;/code&gt; shortcut will override any falsy input value. If you expect a falsy value, you must explicitly check for &lt;code&gt;argument === undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This method only allows the last arguments to be optional - you cannot make an optional first parameter, middle parameter, or combination of parameters optional. The next methods let you position optional arguments anywhere.&lt;/p&gt;

&lt;h4 id='method_2_the_arguments_variable'&gt;Method 2: The arguments variable&lt;/h4&gt;

&lt;p&gt;All javascript functions get passed an implicit &lt;code&gt;arguments&lt;/code&gt; variable when they&amp;#8217;re called. &lt;code&gt;arguments&lt;/code&gt; is an array containing the values of all the arguments passed to the function. Here&amp;#8217;s a function that takes any arguments and &lt;code&gt;alert()&lt;/code&gt;&amp;#8217;s them:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;alertArgs&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;arg1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mf'&gt;12.3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;arg4&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;alertArgs&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;alert&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;JSON&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;stringify&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
    &lt;span class='cm'&gt;/* alerts &amp;#39;[ &amp;quot;arg1&amp;quot;, 12.3, true, &amp;quot;arg4&amp;quot; ]&amp;#39; */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;hostname&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='mi'&gt;80&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='cm'&gt;/* example: do a GET request to www.example.com on port 80 */&lt;/span&gt;
&lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;www.example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='method_3_the_object_literal'&gt;Method 3: The object literal&lt;/h4&gt;

&lt;p&gt;Javascript has a cheap and easy object literal syntax, so why not use this to make flexible and readable optional arguments?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;hostname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='p'&gt;{};&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;port&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='mi'&gt;80&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;method&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;www.example.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nx'&gt;port&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;8080&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;method&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;POST&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='nx'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;www.google.com&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that you need to ensure that an object is passed into &lt;code&gt;options&lt;/code&gt;, replace it with an empty object &lt;code&gt;{}&lt;/code&gt;, or you will get errors trying to read properties from &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id='a_combination_of_all_three_methods'&gt;A combination of all three methods&lt;/h4&gt;

&lt;p&gt;Here&amp;#8217;s an example, from node.js&amp;#8217;s process.watchFile(filename, options, listener) function. It&amp;#8217;s used to watch &lt;code&gt;filename&lt;/code&gt; for changes, calling &lt;code&gt;listener&lt;/code&gt; when it does. In this function, the &lt;code&gt;options&lt;/code&gt; argument is optional:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;watchFile&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;filename&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;listener&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;typeof&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;object&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
    &lt;span class='nx'&gt;listener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{};&lt;/span&gt;
    &lt;span class='nx'&gt;listener&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;persistent&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;persistent&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;true&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;interval&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;options&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;interval&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  
  &lt;span class='cm'&gt;/* SNIP: main function logic */&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='cm'&gt;/* example: watch file &amp;#39;/etc/passwd&amp;#39; for changes */&lt;/span&gt;
&lt;span class='nx'&gt;process&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;watchFile&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/etc/passwd&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
   &lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;passwd file changed&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Peter Norvig's "Design Patterns in Dynamic Programming"</title>
   <link href="http://www.markhansen.co.nz/dynamic-patterns/" />
   <updated>2010-01-15T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/dynamic-patterns</id>
   <content type="html">&lt;p&gt;Today I read something that&amp;#8217;s been sitting in my bookmarks for a few months now: Peter Norvig&amp;#8217;s 1996 &lt;a href='http://norvig.com/design-patterns/'&gt;slides&lt;/a&gt; on Design Patterns in Dynamic Programming.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been toying around with dynamic languages a lot lately, and I&amp;#8217;ve been excited at the flexibility and simplicity offered by features like first-class functions and types. These features are noticeably absent from traditional languages like Java and C++.&lt;/p&gt;

&lt;p&gt;It was a bit tricky to understand the slides where the examples are written in &lt;a href='http://en.wikipedia.org/wiki/Dylan_(programming_language)'&gt;Dylan&lt;/a&gt;, a language I&amp;#8217;d never heard of before today. Dylan is a very Ruby-like language developed in the early 1990s by Apple.&lt;/p&gt;

&lt;p&gt;The slides make a good case for using languages with first-class types and first class functions (i.e. you can pass functions and types as variables at runtime). Common patterns like Factory, Strategy, and Observer become simpler. Here&amp;#8217;s a few examples:&lt;/p&gt;

&lt;h3 id='strategy_pattern'&gt;Strategy Pattern&lt;/h3&gt;

&lt;p&gt;You don&amp;#8217;t need full-blown classes just to hold a function/routine. Just pass the function!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;bird&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='nx'&gt;observers&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='p'&gt;[]&lt;/span&gt; 
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;birdObserver&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='nx'&gt;onBirdChange&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
        &lt;span class='nx'&gt;alert&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;The Bird Moved!&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt; 
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='nx'&gt;bird&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;observers&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='nx'&gt;birdObserver&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;onBirdChange&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='factory_pattern'&gt;Factory Pattern&lt;/h3&gt;

&lt;p&gt;The Factory Pattern defers deciding the type of an object instatiation till runtime. This is trivial with first-class types:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;carType&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;getTypeFromConfigFile&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;car&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;carType&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;createCar&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='observer_pattern'&gt;Observer Pattern&lt;/h3&gt;

&lt;p&gt;The Observer pattern calls a function somewhere when an object changes. Of course, this gets simpler when functions are first-class. Without first-class functions, observers need to inherit a common base class. With first-class functions, you can maintain a list of observers as a list of functions, and one object can observe many others easily.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Changing the Minix3 Bootimage</title>
   <link href="http://www.markhansen.co.nz/minix-device-driver/" />
   <updated>2009-11-05T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/minix-device-driver</id>
   <content type="html">&lt;p&gt;(or: how to add a device driver to Minix3 without bricking your bootimage)&lt;/p&gt;

&lt;p&gt;In this tutorial, we will duplicate the Minix memory device driver. The memory driver is a very small driver, and can serve as a simple working implementation of the driver interface. Once we have duplicated the driver, we will test it by modifying it, adding a new minor device to it. This driver will retrieve the system uptime. Note: I will be using Minix 3.1.4 for the examples.&lt;/p&gt;

&lt;h3 id='background'&gt;Background&lt;/h3&gt;

&lt;p&gt;When you read from a file in Minix3, execution passes through the file system and device driver:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;read(fd, &amp;amp;buf, bytes)&lt;/code&gt; call from a user-space program (e.g. &lt;code&gt;/bin/cat&lt;/code&gt;) passes a message to the filesystem (&lt;code&gt;/usr/src/servers/vfs&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;the filesystem dispatches to a device driver, based on its table mapping major device numbers to device driver process numbers in &lt;code&gt;/usr/src/servers/vfs/dmap.c&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The device driver recieves a message from the filesystem, and performs the read call.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We must add information about the driver to files in &lt;code&gt;/usr/src/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;drivers/Makefile&lt;/code&gt; - organises compilation of drivers&lt;/li&gt;

&lt;li&gt;&lt;code&gt;kernel/table.c&lt;/code&gt; - this defines the programs in the bootimage&lt;/li&gt;

&lt;li&gt;&lt;code&gt;tools/Makefile&lt;/code&gt; - defines the location of files in the bootimage&lt;/li&gt;

&lt;li&gt;&lt;code&gt;include/minix/com.h&lt;/code&gt; - defines process numbers of drivers&lt;/li&gt;

&lt;li&gt;&lt;code&gt;servers/vfs/dmap.c&lt;/code&gt;, - defines device major-number -&amp;gt; device process number mappings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='1_duplicate_the_memory_driver'&gt;1: Duplicate the memory driver&lt;/h3&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; /usr/src/drivers/
cp -r memory mydriver
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, add a line to the &lt;code&gt;/usr/src/drivers/Makefile&lt;/code&gt;, in the &lt;code&gt;all install depend
clean:&lt;/code&gt; section, telling it to compile whatever&amp;#8217;s in the &lt;code&gt;mydriver&lt;/code&gt; directory. Put it in just before the memory driver, as the memory driver must be last for some reason.&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ./mydriver &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='k'&gt;$(&lt;/span&gt;MAKE&lt;span class='k'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Also, we want our driver to run when the computer boots - we want it in the bootimage. So add a line to the &lt;code&gt;bootimage&lt;/code&gt; section of the makefile, again, just before the memory driver:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ./mydriver &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='k'&gt;$(&lt;/span&gt;MAKE&lt;span class='k'&gt;)&lt;/span&gt; build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can test that this works by observing the make program enter your &lt;code&gt;mydriver&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; /usr/src/drivers
make
make image
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='2_add_the_driver_to_the_bootimage'&gt;2: Add the driver to the bootimage&lt;/h3&gt;

&lt;p&gt;This is a big step, and if something goes wrong, your new system image will not boot. Don&amp;#8217;t worry! Minix gives you the option to boot into the original, working image instead, if something goes wrong.&lt;/p&gt;

&lt;p&gt;First, give your new driver a process number. Edit &lt;code&gt;/usr/src/include/minix/com.h&lt;/code&gt;, and find where &lt;code&gt;INIT_PROC_NR&lt;/code&gt; is defined. These task numbers are indexes into the bootimage table defined in &lt;code&gt;kernel/table.c&lt;/code&gt;, and INIT must be last. So increment &lt;code&gt;INIT_PROC_NR&lt;/code&gt; and insert &lt;code&gt;MYDRIVER_PROC_NR&lt;/code&gt; just before INIT&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='cp'&gt;#define MYDRIVER_PROC_NR    9&lt;/span&gt;
&lt;span class='cp'&gt;#define INIT_PROC_NR        10 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, edit &lt;code&gt;/usr/src/kernel/table.c&lt;/code&gt;, and add in the new driver just before INIT in the process table, again. The last three lines of my &lt;code&gt;bootimage image[]&lt;/code&gt; look like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;VM_PROC_NR&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;        &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='n'&gt;SRV_F&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;32&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;      &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='n'&gt;SRV_T&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;SRV_M&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;vm_c&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;vm&amp;quot;&lt;/span&gt;    &lt;span class='p'&gt;},&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;MYDRIVER_PROC_NR&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='n'&gt;SVM_F&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;      &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='n'&gt;SRV_T&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;SYS_M&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;mem_c&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;mydriver&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;},&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;INIT_PROC_NR&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;      &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='n'&gt;USR_F&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;USER_Q&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='n'&gt;USR_T&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;USR_M&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;no_c&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;    &lt;span class='s'&gt;&amp;quot;init&amp;quot;&lt;/span&gt;  &lt;span class='p'&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I just copied the fields from the memory device&amp;#8217;s line, changing the process number and name. The order is important - it must be consistent throughout the files dealing with the bootimage (&lt;code&gt;kernel/table.c&lt;/code&gt;, &lt;code&gt;tools/Makefile&lt;/code&gt;, and &lt;code&gt;include/minix/com.h&lt;/code&gt;), or your system will not boot.&lt;/p&gt;

&lt;p&gt;Next, edit &lt;code&gt;/usr/src/tools/Makefile&lt;/code&gt;. This file specifies the parameters passed to the program that constructs the bootimage, in the &lt;code&gt;PROGRAMS&lt;/code&gt; variable. Add a line to this, just before &lt;code&gt;../servers/init/init&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;../drivers/mydriver/memory&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;memory&lt;/code&gt; is the name of the driver program produced by the Makefile in mydriver. You&amp;#8217;ll probably want to change this at some point. When you do, change the reference in &lt;code&gt;tools/Makefile&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;The driver&amp;#8217;s now added to the bootimage. Try recompiling the system, and rebooting into the new boot image.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;   
&lt;span class='nb'&gt;cd&lt;/span&gt; /usr/src/tools
make install
shutdown
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If all goes well, your system should reboot happily, and as the kernel starts, listing the programs in the bootimage, you will see &lt;code&gt;mydriver&lt;/code&gt; before &lt;code&gt;init&lt;/code&gt;. If not, try booting into the old (working) bootimage, and run a &lt;code&gt;make fresh
install&lt;/code&gt; from &lt;code&gt;/usr/src/tools&lt;/code&gt;, which will recompile everything from source (and take a long time).&lt;/p&gt;

&lt;p&gt;Excellent! There are now two memory drivers running. However, we can&amp;#8217;t use the new one - the filesystem doesn&amp;#8217;t know about it yet - it doesn&amp;#8217;t have a major device number.&lt;/p&gt;

&lt;h3 id='3_add_the_device_to_the_file_server'&gt;3. Add the device to the File Server&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/usr/src/servers/vfs/dmap.c&lt;/code&gt;. In this file, there is a &lt;code&gt;struct dmap dmap&lt;/code&gt; containing a mapping from major device number to process number, and other info. Find a major device number (index in the table) that is marked &amp;#8216;not used&amp;#8217; (on my system, #9 was not used), and replace it with data copied from the memory device driver above, changing &lt;code&gt;MEM_PROC_NR&lt;/code&gt; to &lt;code&gt;MYDRIVER_PROC_NR&lt;/code&gt; and &lt;code&gt;&amp;quot;memory&amp;quot;&lt;/code&gt; to &lt;code&gt;&amp;quot;mydriver&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='c'&gt;&lt;span class='n'&gt;DT&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;gen_opcl&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;gen_io&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;MYDRIVER_PROC_NR&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;mydriver&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, calls to that major device number will dispatch to the handlers defined in &lt;code&gt;/usr/src/drivers/mydriver&lt;/code&gt;. You can modify these routines to execute arbitrary code, and return anything.&lt;/p&gt;

&lt;p&gt;To make a special file to access this new driver, use &lt;code&gt;mknod&lt;/code&gt; to make a character special file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;mknod myspecialfile c &lt;span class='o'&gt;[&lt;/span&gt;major number&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;minor number&lt;span class='o'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can then access your driver through this special file, as you would any other file.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;cat myspecialfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now you can modify your second memory driver to return whatever you want on a read() call.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Dodgy Pizza</title>
   <link href="http://www.markhansen.co.nz/dodgy-pizza/" />
   <updated>2009-10-24T00:00:00+11:00</updated>
   <id>http://www.markhansen.co.nz/dodgy-pizza</id>
   <content type="html">&lt;p&gt;With some friends last night, I got some pizza. As the pizza delivery boy answered the door, he asked to see the credit card we had used to order the pizza, remarking &amp;#8220;We have had 70 cases of credit card fraud&amp;#8221;. This, from a store that just opened two weeks ago, is crazy. There must be a reason why Hells Pizza is getting so much fraud!&lt;/p&gt;

&lt;p&gt;Quick! What&amp;#8217;s wrong with this picture?&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.hell.co.nz'&gt;&lt;img alt='Hells Pizza asking for credit card number on unsecured page' src='/images/hells.png' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a clue:&lt;/p&gt;

&lt;p&gt;&lt;img alt='Google chrome website information' src='/images/chromeinfo.png' /&gt;&lt;/p&gt;

&lt;p&gt;See that link &amp;#8220;Click here to verify merchant details&amp;#8221;? Here&amp;#8217;s what happens when I click it:&lt;/p&gt;

&lt;p&gt;&lt;img alt='Invalid website' src='/images/paymark.png' /&gt;&lt;/p&gt;

&lt;p&gt;Hells Pizza&amp;#8217;s website:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses unsecured HTTP (plaintext transmission!)&lt;/li&gt;

&lt;li&gt;Has no certificate to ensure I&amp;#8217;m actually at the real hells pizza website&lt;/li&gt;

&lt;li&gt;Has a link to a validation website telling me their website is invalid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;em&gt;serious problems&lt;/em&gt; for a company taking their customer&amp;#8217;s credit card number over the internet.&lt;/p&gt;

&lt;h3 id='unsecured_http'&gt;Unsecured HTTP&lt;/h3&gt;

&lt;p&gt;This means everything is transmitted in plain text. Anyone on the connection between my computer and hell.co.nz can watch it, inspect it, or even change it. If they&amp;#8217;re transmitting my credit card number like this, it&amp;#8217;s also against VISA&amp;#8217;s terms and conditions.&lt;/p&gt;

&lt;h3 id='no_certificate'&gt;No certificate&lt;/h3&gt;

&lt;p&gt;Certificates say &amp;#8220;A trusted authority has vouched that this is indeed the real website of hell.co.nz, and not some imposter&amp;#8221;. Since there is no certificate, I have no way of knowing that I&amp;#8217;m looking at the real Hells Pizza website! It could be running off a completely different server, anywhere in the world and I&amp;#8217;d have no idea that I was actually giving my credit card number to someone in, say, Nigeria.&lt;/p&gt;

&lt;p&gt;Sounds farfetched? There are many ways I could be redirected to a different server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;#8217;s being transmitted over unsecured HTTP, so anyone between my computer and hell&amp;#8217;s pizza&amp;#8217;s server could intercept the communication, reply as if they were hell&amp;#8217;s server, and issue a redirect request to their server.&lt;/li&gt;

&lt;li&gt;DNS cache poisoning. Any of your DNS caches could be poisoned to redirect www.hell.co.nz to a fake host. Your browser, your operating system, your router, and your ISP all operate their own DNS caches. Any of these could be poisoned.&lt;/li&gt;

&lt;li&gt;HOSTS file poisoning. Every time your computer visits a website, it checks the hosts file. And if the hosts file says &amp;#8220;hellspizza.co.nz is at this ip address&amp;#8221;, my request (and credit card number) will be sent to that ip address.&lt;/li&gt;

&lt;li&gt;Hell&amp;#8217;s Pizza forgets to renew their domain name, and someone else snaps it up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='sniffing'&gt;Sniffing&lt;/h3&gt;

&lt;p&gt;I popped open my favorite network sniffer &lt;a href='http://www.wireshark.org'&gt;Wireshark&lt;/a&gt; to have a closer look at the network traffic leaving my computer, and whether it was encrypted when I sent my credit card number.&lt;/p&gt;

&lt;p&gt;The whole website is done as a Flash application, and internally, the application &lt;em&gt;does use HTTPS to transmit credit card numbers&lt;/em&gt;. This means that not I, nor anybody else on the network, can listen in on the credit card numbers in transit.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;For now, there&amp;#8217;s no way for me to know if I&amp;#8217;m dealing with the real Hell&amp;#8217;s Pizza website when I&amp;#8217;m entering my credit card details.&lt;/p&gt;

&lt;p&gt;I know it&amp;#8217;s encrypting my credit card details before sending them, but &lt;em&gt;I can&amp;#8217;t be sure who it&amp;#8217;s sending them to&lt;/em&gt;. This is not good enough for a website handling customer&amp;#8217;s credit card numbers.&lt;/p&gt;

&lt;p&gt;Hell&amp;#8217;s Pizza needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;serve up their content using &lt;a href='http://en.wikipedia.org/wiki/HTTPS'&gt;Secure HTTP&lt;/a&gt;, so that nobody can alter their website in the network.&lt;/li&gt;

&lt;li&gt;get a &lt;a href='http://www.verisign.com/'&gt;certificate&lt;/a&gt; for their website, so that I know I&amp;#8217;m looking at the real Hell&amp;#8217;s Pizza website.&lt;/li&gt;

&lt;li&gt;Investigate why their paymark &amp;#8216;site validation&amp;#8217; link tells me the site is Not Valid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Till then, I know who I&amp;#8217;ll be ordering from:&lt;/p&gt;

&lt;p&gt;&lt;img alt='Dominos Pizza Certificate' src='/images/dominos.png' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Private methods and variables in Javascript</title>
   <link href="http://www.markhansen.co.nz/javascript-private-members/" />
   <updated>2009-08-24T00:00:00+10:00</updated>
   <id>http://www.markhansen.co.nz/javascript-private-members</id>
   <content type="html">&lt;p&gt;Till yesterday, I believed there was no way to encapsulate private methods and variables in javascript:&lt;/p&gt;

&lt;p&gt;There are no &amp;#8216;private&amp;#8217; or &amp;#8216;public&amp;#8217; keywords, like in Java or C#. There are no classes as such, just objects inheriting directly from other objects. And all fields on any object are public.&lt;/p&gt;

&lt;p&gt;But, it turns out there is a way to make private members in javascript, using closures.&lt;/p&gt;

&lt;p&gt;What&amp;#8217;s a closure?&lt;/p&gt;

&lt;p&gt;If an outer function returns an inner function, the inner function still has access to the variables of the outer function, &lt;em&gt;even after the outer function has returned&lt;/em&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;outerFunction&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;outerFunctionVariable&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;id&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;innerFunction&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;outerFunctionVariable&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
 
&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;outerFunction&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nx'&gt;a&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='c1'&gt;//returns 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We are calling the inner function after the outer function has returned, but the inner function still has access to the outer function&amp;#8217;s methods. Magic!&lt;/p&gt;

&lt;p&gt;How can you access the local variables of a function after it has returned, the stack frame will be popped right off and the variables will be lost, right?&lt;/p&gt;

&lt;p&gt;Not necessarily. When you use a closure, the stack frame is not popped off. It&amp;#8217;s saved somewhere safe, and inner functions can still get at it.&lt;/p&gt;

&lt;p&gt;Morris Johns has some &lt;a href='http://blog.morrisjohns.com/javascript_closures_for_dummies.html'&gt;excellent examples&lt;/a&gt; illustrating this.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example of a plain vanilla javascript object.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;car&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;odometer&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;100000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;drive&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;distance&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;distance&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;odomoter&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='nx'&gt;distance&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I have a &lt;code&gt;drive&lt;/code&gt; function that increases the odometer, and guards against winding it back. Except &lt;code&gt;odometer&lt;/code&gt; is a public member, so anyone can change it. Uh-oh.&lt;/p&gt;

&lt;p&gt;Functions in javascript create a new scope, so we can &amp;#8216;hide&amp;#8217; &lt;code&gt;odometer&lt;/code&gt; inside a function. We still need to read the odometer reading, so we can return a function &lt;code&gt;getOdometer()&lt;/code&gt;. Through closure, the inner function &lt;code&gt;getOdometer()&lt;/code&gt; has access to the odometer member of the outer function &lt;code&gt;makeCar()&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;makeCar&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;initialOdometer&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;privateOdometer&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;initialOdometer&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='s2'&gt;&amp;quot;getOdometer&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
            &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;privateOdometer&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='s2'&gt;&amp;quot;drive&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;distance&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;distance&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nx'&gt;privateOdometer&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='nx'&gt;distance&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(Note: We are not using &lt;code&gt;this&lt;/code&gt; to access the odometer reading any more. &lt;code&gt;this&lt;/code&gt; is not needed - we have a direct reference to &lt;code&gt;privateOdometer&lt;/code&gt; in the closure)&lt;/p&gt;

&lt;p&gt;We can then instantiate a really old car, setting its private odometer:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;reallyOldCar&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;makeCar&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;180000&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can&amp;#8217;t get or set the odometer directly: there&amp;#8217;s no &lt;code&gt;privateOdometer&lt;/code&gt; field on the object we returned:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;privateOdometer&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c1'&gt;//undefined &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;However we can use &lt;code&gt;getOdometer()&lt;/code&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getOdometer&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='c1'&gt;//180000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can drive the car halfway around the world, and recheck the odometer.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;drive&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;20000&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getOdometer&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='c1'&gt;//200000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then we can complete the journey, circling the world.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;drive&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;20000&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; 
&lt;span class='nx'&gt;reallyOldCar&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getOdometer&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='c1'&gt;//220000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Brilliant! Private variables in javascript. You can apply exactly the same technique for private methods.&lt;/p&gt;

&lt;p&gt;props to &lt;a href='http://www.crockford.com/'&gt;Douglas Crockford&lt;/a&gt; for &lt;a href='http://javascript.crockford.com/private.html'&gt;explaining this pattern&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 
</feed>
