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

<channel>
	<title>overwatering</title>
	<atom:link href="http://www.overwatering.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.overwatering.org/blog</link>
	<description>Random musings on fish, books and occasionally programming.</description>
	<lastBuildDate>Mon, 07 Nov 2011 07:06:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Lessons from a Pure JavaScript Project: CoffeeScript</title>
		<link>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project-coffeescript/</link>
		<comments>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project-coffeescript/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 06:18:30 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[jasmine]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=396</guid>
		<description><![CDATA[This is the second post in a series on observations and questions from implementing a single page pure JavaScript web application for a recent project. For background and the other posts in this series, see the introduction

Before joining this project I spent two weeks on another project helping them make a technology decision. This other [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second post in a series on observations and questions from implementing a single page pure JavaScript web application for a recent project. For background and the other posts in this series, see the <a href="http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project/">introduction</a></p>

<p>Before joining this project I spent two weeks on another project helping them make a technology decision. This other project had a requirement for a sophisticated web UI. The choices were Flash or JavaScript. After helping with some spikes the team decided to use JavaScript. As this would be the first time anyone on the team would be using JavaScript, I made some recommendations. One of these was not to use <a href="http://jashkenas.github.com/coffee-script/">CoffeeScript</a>.</p>

<p>I was wrong.</p>

<p>It was a new project with a team of people who weren&#8217;t very familiar with JavaScript and certainly had not written a large JavaScript application. I felt that CoffeeScript would be another new thing for what until very recently had been a Java team. It would be better to first learn JavaScript; understand that and then learn how CoffeeScript can make the language better.</p>

<p>After that short consulting gig, I started on this project on the following Monday. This was another sophisticated JavaScript UI application. But it was already about two months into development. This project had already decided not to use CoffeeScript, for similar reasons as I&#8217;d gone through on the previous Friday. It was like jumping forward in time two months. More than anything else, with the amount of JavaScript code we had, the syntax was just agony. It simply made the code harder to read. This may sound like a small detail, but I believe very strongly that code needs to be readable by humans above everything else. JavaScript&#8217;s syntax is simply woefully inappropriate for the style of programming the language is otherwise very tuned for.</p>

<p>As I mentioned above, we used <code>underscore.js</code> pretty heavily. This encourages a lot of anonymous functions passed as parameters, something that reads very nicely in Ruby. In JavaScript, a simple loop to lowercase every string in an array reads pretty painfully.</p>

<pre><code>var keyNames = _.map(recipientNames, function(name) {
  return name.toLowerCase();
});
</code></pre>

<p>By the way, the glyph <code>});</code> is henceforth known as the coffee-break.</p>

<p>The absolute bare minimum for a lambda is <code>function() { return; }</code>. That&#8217;s 19 characters! 19! Here&#8217;s the same code in CoffeeScript:</p>

<pre><code>keyNames = _.map recipientNames, (name) -&gt; name.toLowerCase()
</code></pre>

<p>That is one plausible line. Yes please, can I have some more? This may seem like a small detail on its own. It&#8217;s just syntax, you say. You may disagree with my opinion that syntax is critical. Allow me to offer another example from this project. A couple of us are Ruby programmers, and fans of the very declarative style of test that is possible in RSpec, using <code>let</code>.</p>

<pre><code>describe "an account" do
  let(:subject) { Account.new(:balance =&gt; balance) }
  describe "positive balance" do
    let(:balance) { 100 }
    it "should allow withdrawals" …
  end
end
</code></pre>

<p>The JavaScript unit testing library of choice, <a href="http://pivotal.github.com/jasmine/">Jasmine</a> doesn&#8217;t (yet) include any equivalent of this. So I whipped something up pretty quickly to allow the equivalent:</p>

<pre><code>describe("an account", function() {
  define({subject: function(ctxt) { return createAccount({balance: ctxt.balance()}); }}, function(ctxt) {
    describe("positive balance", function() {
      define(ctxt, {balance: function() { return 100; }}, function(ctxt) {
        it("should allow withdrawals", function() { …; });
      });
    });
  });
});
</code></pre>

<p>There are two problems here. Firstly, JavaScript doesn&#8217;t have <code>instance_eval</code> or <code>method_missing</code> so you can&#8217;t decorate a lexical scope before passing it downwards, hence explicitly passing down the <code>ctxt</code> parameter. Actually, while the lack of <code>method_missing</code> is a real pain, I think <code>instance_eval</code> is no great loss and I would happily write much, much code in a language that doesn&#8217;t allow libraries to mess with name bindings quite so liberally.</p>

<p>Secondly, the sheer noise of the JavaScript syntax is incredibly painful. Here is the equivalent, translated directly into CoffeeScript.</p>

<pre><code>describe "an account", -&gt;
  define
    subject: (ctxt) -&gt; createAccount balance: ctxt.balance()
  , (ctxt) -&gt;
    describe "positive balance", -&gt;
      define ctxt,
        balance: -&gt; 100
      , (ctxt) -&gt;
        it "should allow withdrawals", -&gt; … 
</code></pre>

<p>The most interesting thing from this conversion, to me, is that it shows that the double-nesting of <code>define</code>s and <code>describe</code>s is actually pretty unclear. In my copious spare time I&#8217;m working on a better implementation of that <code>define()</code> function, in the hope of getting it added to Jasmine. If I&#8217;d been staring at that second version throughout the project I would have started down that path earlier.</p>

<p>But the better syntax is not everything; the other features in CoffeeScript, like list comprehensions and default arguments are Good Things and would have been very nice to have.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project-coffeescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons from a Pure JavaScript Project</title>
		<link>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project/</link>
		<comments>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 05:59:01 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[jasmine]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=394</guid>
		<description><![CDATA[Our team is wrapping up the first release of a pure JavaScript, single page web application. No one on the team has ever built one of these before and it seems they are becoming the new hotness, so I thought it would be useful to attempt to write down some observations and questions. Hopefully, you [...]]]></description>
			<content:encoded><![CDATA[<p>Our team is wrapping up the first release of a pure JavaScript, single page web application. No one on the team has ever built one of these before and it seems they are becoming the new hotness, so I thought it would be useful to attempt to write down some observations and questions. Hopefully, you can learn something and I can be pointed in the direction of doing it better next time.</p>

<p>The application is a mobile web app for a customer who already has a number of native apps for iPhone and Android. All these apps use an existing set of services to access the core data. Our app used <a href="http://jquerymobile.com/">JQuery Mobile</a> and <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> as the only libraries. For testing, we used <a href="http://pivotal.github.com/jasmine/">Jasmine</a> and <a href="http://cukes.info/">cucumber</a>.</p>

<p>Originally, I wanted to post this as a single post, but it go long. Very long. Looking back on our project, there were four things I&#8217;d like to try doing differently.</p>

<ul>
<li><p><a href="http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project-coffeescript/">We didn&#8217;t use CoffeeScript</a> for what felt like very good reasons at the time. In hindsight, this was a mistake.</p></li>
<li><p>Writing functional tests for a pure JavaScript application is a different problem requiring different solutions than a typical web application.</p></li>
<li><p>Your JavaScript application is going to end up as a very sophisticated GUI application, with more complex state and flow management than most typical web applications. Consider your use of models and controllers very seriously.</p></li>
<li><p>Web applications have long had to deal with the Back and Refresh browser buttons. A single page JavaScript application adds some new wrinkles. But I think that HTML 5 also includes some neat solutions.</p></li>
</ul>

<p>As I get my posts written, I&#8217;ll update the above with links.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/lessons-from-a-pure-javascript-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Illinois, Texas, Cali and Accents</title>
		<link>http://www.overwatering.org/blog/2011/10/illinois-texas-cali-and-accents/</link>
		<comments>http://www.overwatering.org/blog/2011/10/illinois-texas-cali-and-accents/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 21:01:11 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[livingintheus]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[coffee]]></category>
		<category><![CDATA[food]]></category>
		<category><![CDATA[illinois]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[texas]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=390</guid>
		<description><![CDATA[Inspired by some of my friends and family who have also moved overseas this year, it is time to start writing about living in the US.

The first week and a half was Chicago. A couple of days of thrilling things like opening a bank account and applying for my social security number. Banks are different [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://adventures-of-jane.blogspot.com/">some</a> of my <a href="http://davehasgone.blogspot.com/">friends</a> and <a href="http://dnaoflondon.blogspot.com/">family</a> who have also moved overseas this year, it is time to start writing about living in the US.</p>

<p>The first week and a half was Chicago. A couple of days of thrilling things like opening a bank account and applying for my social security number. Banks are different over here. There are only two account packages that were offered, and both only have a monthly fee of $8 which is waived at the drop of a hat. And banks are open on Saturdays! The horror.</p>

<p>The week on the beach was a good break. In the end, with public holidays, transition leave and beach time, it was three weeks between stopping work in Australia and starting on a project over here.</p>

<p>Of course, the coffee is still almost universally rubbish. To counter that, we spent quite awhile in Chicago hunting for the perfect burger. After being repeatedly scared off by threats of three hour waits we finally had a really good one the afternoon I was flying out.</p>

<p>And the first project was in Plano, Texas. That&#8217;s a suburb of Dallas. And a complete wasteland. It&#8217;s a dead-flat plain, smeared with office parks and strip malls. I didn&#8217;t know what a strip mall was until I got down there. I see why they inspire such horror. Around Plano is basically nothing, but fortunately we stayed in a hotel in another suburb about 15 minutes to the South: Addison. Addison at least has a strip of franchise restaurants, and kind-of-bars. The highlight of that was the evening we ate dinner in a Greek restaurant, while watching a car on fire across the road. Metre high flames and plumes of black smoke. Very exciting.</p>

<p>By &#8216;we&#8217; I mean the ThoughtWorks team. Just two other travellers. They started to think I liked Starbucks. I tried to put a stop to that, but I couldn&#8217;t help but be excited at almost drinkable coffee. Sigh.</p>

<p>Dallas has three redeeming features: first, Texas BBQ — hell yeah! It&#8217;s completely unlike anything I&#8217;ve had and really amazing. Half a pound of meat, served on paper, eaten with your fingers, no sauce, sitting in a dirty shack. Well worth it. Lockhart&#8217;s Smokehouse in Oak Cliff, if you&#8217;re ever down that way.</p>

<p>Second is the 6th Floor Museum. In the Old Texas Book Depository. That&#8217;s right, a museum dedicated to the assassination of JFK. It&#8217;s actually a good museum. Small enough to really see; respectful without being sycophantic; and complete: it finishes with the conspiracy theories. In one corner they have recreated Oswald&#8217;s perch, as it was when they first found it. Down in the plaza outside it&#8217;s a different story. There&#8217;s an &#8216;X&#8217; on the road at The Spot. And the grassy knoll is covered in lunatics delivering speeches and handing out pamphlets. Again, if you&#8217;re there, then go.</p>

<p>And finally, my accent was quite novel. Apart from the teasing and joking from the team, I walked into a pub and wanted to order a beer. I made the mistake of trying to order by name, instead of just pointing. There&#8217;s a San Francisco beer I quite like called &#8216;Anchor Steam.&#8217; Some of you would have already seen where this is going. I had to repeat myself several times. The waitress went to stare at the beer fridge. Conferred with a couple of other staff. And then returned with another waitress. She&#8217;d brought over a Brit to translate for me. Sigh. The trick is to really hoe into those &#8216;Rs&#8217;.</p>

<p>Working with the client was kind of fun. I spent a day pairing with a very junior client dev. She was from Louisiana. She has only been in a taxi twice. At stand-up, the next day she said that pairing was fun but a bit difficult to follow. A helpful ThoughtWorker then said &#8220;That&#8217;s just Giles.&#8221; Very quickly she said &#8220;Oh, but I love his accent!&#8221; In a Southern drawl. So I&#8217;m playing up the Australian thing. They&#8217;re all my mates, and there are no worries to be seen anywhere.</p>

<p>I&#8217;ve finished up in Dallas, and spent the weekend back in Chicago. And now I&#8217;m on another plane. This time I&#8217;m off to San Francisco. Joining a big team out there, I&#8217;ll probably be here until September, I think. The client is at 2nd and Mission, and we&#8217;re staying in hotels around Union Square. This should be quite a lot of fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/illinois-texas-cali-and-accents/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steve.</title>
		<link>http://www.overwatering.org/blog/2011/10/steve/</link>
		<comments>http://www.overwatering.org/blog/2011/10/steve/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 04:34:42 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[career]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[glove]]></category>
		<category><![CDATA[apple]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=388</guid>
		<description><![CDATA[As everyone knows by now, Steve Jobs died last Wednesday, 5th of October. I first found about it while browsing twitter, sitting in the departure lounge of San Francisco International airport. I think my tweets from then tell the story.


5:59pm: Fuck.
6:00pm: 


I started programming for the Apple //e back in 1986, when I was seven. [...]]]></description>
			<content:encoded><![CDATA[<p>As everyone knows by now, <a href="http://en.wikipedia.org/wiki/Steve_Jobs">Steve Jobs</a> died last Wednesday, 5th of October. I first found about it while browsing twitter, sitting in the departure lounge of San Francisco International airport. I think my tweets from then tell the story.</p>

<ul>
<li><a href="http://twitter.com/#!/gga/status/121751444574572545">5:59pm</a>: Fuck.</li>
<li><a href="http://twitter.com/#!/gga/status/121751720341680128">6:00pm</a>: </li>
</ul>

<p>I started programming for the Apple //e back in 1986, when I was seven. And ever since then I&#8217;ve been programming. And while I have only recently been programming professionally on and for Apple devices, I never stopped using Apple computers. Yes, all through the dark years of the 1990s I used and programmed Macs.</p>

<p>If I had been born in an early time I imagine I would have been an engineer of some more mechanical kind. If I was born any later I would still have been a programmer.</p>

<p>But if I hadn&#8217;t been exposed to Apple and Macs I would have been a different kind of programmer. Not necessarily better or worse, but <a href="http://www.overwatering.org/blog/2008/09/on-the-nature-of-my-damage/">definitely different</a>.</p>

<p>So as one person whose life was changed by the influence of someone I never met, thank you Steve. You will be missed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/steve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A modest proposal towards reusable step definitions for Cucumber</title>
		<link>http://www.overwatering.org/blog/2011/10/a-modest-proposal-towards-reusable-step-definitions-for-cucumber/</link>
		<comments>http://www.overwatering.org/blog/2011/10/a-modest-proposal-towards-reusable-step-definitions-for-cucumber/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 04:35:25 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[cucumber]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=382</guid>
		<description><![CDATA[



While the title is a nod to the original modest proposal this is completely serious. I just liked the title. Pez thought I should be more clear.




Typically, cucumber step definitions look like this:

When /^I select the recipient named "([^"]*)"$/ do &#124;recipientname&#124;
 within_jqm_page do
   page.find('a', :text =&#62; recipientname).click
 end
end


Step definitions implemented like this end [...]]]></description>
			<content:encoded><![CDATA[<div align="center">

<div style="text-align: left; width: 80%; background-color: rgb(255, 255, 153); font-size: 65%; padding-bottom: 10px; padding-left: 10px; padding-right: 10px;">

While the title is a nod to the original <a href="http://en.wikipedia.org/wiki/A_Modest_Proposal">modest proposal</a> this is completely serious. I just liked the title. <a href="http://twitter.com/perrynfowler">Pez</a> thought I should be more clear.

</div>
</div>

<p>Typically, <a href="http://cukes.info/">cucumber</a> step definitions look like this:</p>

<pre><code>When /^I select the recipient named "([^"]*)"$/ do |recipientname|
 within_jqm_page do
   page.find('a', :text =&gt; recipientname).click
 end
end
</code></pre>

<p>Step definitions implemented like this end up becoming a pain to re-use. Essentially you are calling a function, except to do so you have to construct a string, and then execute that. We&#8217;ve all seen how that ends.</p>

<pre><code>Given /^all the entered recipient details are valid$/ do
  When %{I fill in "name" with "Valid Name"}
  And %{I fill in "phone" with "4152234567"}
  And %{I fill in "email1" with "valid.email@example.com"}
end
</code></pre>

<p>The direct outcome is very hard to maintain step definitions &mdash; like the above &mdash; and thus very poor quality cucumber tests. Patterns like <a href="http://blog.josephwilk.net/cucumber/page-object-pattern.html">page objects</a> and <a href="http://pilchardfriendly.wordpress.com/2011/09/25/test-personas-a-pattern-for-acceptance-tests/">personas</a> take work to extract when following this approach. This approach that is analogous to writing VB6 applications in the early 2000s where all logic was just a double-click on a form button away. And as with VB6, that cucumber directly encourages this approach is part of the problem.</p>

<p>I hear a lot of complaints about cucumber these days. These complaints tend to target the English language test scripts: while business readable acceptance tests may be nice, these are useless if the business is never actually reading the tests.</p>

<p>The unspoken heart of this complaint seems to be the English language tests are responsible for the poor maintainability of the average cucumber test suite. I agree. But that shouldn&#8217;t be the case.</p>

<p>After trying to build well-factored cucumber suites on a few occasions, I pretty much hate the pattern of just attaching anonymous blocks to regular expressions. Instead, I want step definitions that directly invoke methods. Something like:</p>

<pre><code>Given /^I am on the (\w+) page$/ =&gt; :go_to_known_page,
  :on =&gt; { current_user }

class User
  def self.current_user
    …
  end

  def go_to_known_page(page_name)
    visit Page.page_named(page_name)
  end
end

World(User)
</code></pre>

<p>The significant part is in the first two lines. Instead of passing a block to the <code>Given</code>, a symbol for a method to invoke would be passed. This method would be invoked with the arguments matched by the regular expression, after any <code>Transform</code>s have been applied. The <code>:on</code> is optional. This is a block evaluated against the <code>World</code>. If <code>:on</code> is provided, the method would be sent to the result of this block instead.</p>

<p>Yes, this would force you to define classes and attach methods to those. Yes, this would require you to think about the interrelationships of your objects. Yes, this is quite a lot more limited than an arbitrary block of code. Yes, that is exactly the point.</p>

<p>After a quick glance through the cucumber source this does not look difficult to add. Should I go to the effort of adding it?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/a-modest-proposal-towards-reusable-step-definitions-for-cucumber/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Better Line Numbering in emacs</title>
		<link>http://www.overwatering.org/blog/2011/10/better-line-numbering-in-emacs/</link>
		<comments>http://www.overwatering.org/blog/2011/10/better-line-numbering-in-emacs/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 05:59:16 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[text editor hobbyists]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=376</guid>
		<description><![CDATA[Earlier this year while pairing with Julio Maia, an unashamed vim user, I noticed that the line numbers didn&#8217;t count from the top of the file in his editor. Instead, all line numbering was relative to his current line. It looked something like this.



This was really cool. It&#8217;s really easy to navigate and edit when [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this year while pairing with <a href="http://blog.rufiao.com/">Julio Maia</a>, an unashamed <a href="http://www.vim.org/">vim</a> user, I noticed that the line numbers didn&#8217;t count from the top of the file in his editor. Instead, all line numbering was relative to his current line. It looked something like this.</p>

<div style="text-align:center;"><img src="http://www.overwatering.org/blog/wp-content/uploads/2011/10/line-numbers.jpg" alt="line-numbers.jpg" border="0" width="438" height="293" /></div>

<p>This was really cool. It&#8217;s really easy to navigate and edit when you can see how many lines to move without having to count. It also didn&#8217;t hurt pairing. I could just refer to something &#8216;there, on line -10.&#8217; I had to have it. So I hacked it into the <a href="http://www.emacswiki.org/emacs/LineNumbers">linum.el</a> mode that comes with my editor of choice, <a href="http://www.gnu.org/s/emacs/">emacs</a>.</p>

<p>Now that I&#8217;m reading Avdi Grimm&#8217;s emacs reboot, including his article about <a href="http://avdi.org/devblog/2011/09/29/emacs-reboot-11-line-numbers/">line numbering</a>, I thought I should share. At least until I can get this submitted back upstream.</p>

<p>In your <code>linum.el</code> file, add the following after all the existing <code>defcustom</code> forms.</p>

<pre><code>(defcustom linum-offset nil
  "Whether line numbers should be an offset from point or absolute within the buffer."
  :group 'linum
  :type 'boolean)
</code></pre>

<p>And then replace the existing <code>linum-update-window</code> function with the following.</p>

<pre><code>(defun linum-update-window (win)
  "Update line numbers for the portion visible in window WIN."
  (setq start-line (line-number-at-pos))
  (goto-char (window-start win))
  (let ((line (line-number-at-pos))
        (limit (window-end win t))
        (fmt (cond ((stringp linum-format) linum-format)
                   ((eq linum-format 'dynamic)
                    (let ((w (length (number-to-string
                                      (count-lines (point-min) (point-max))))))
                      (concat "%" (number-to-string w) "d")))))
        (width 0))
    (run-hooks 'linum-before-numbering-hook)
    ;; Create an overlay (or reuse an existing one) for each
    ;; line visible in this window, if necessary.
    (while (and (not (eobp)) (&lt;= (point) limit))
      (let* ((offset-line (- line start-line))
             (line-number (if linum-offset offset-line line))
             (str (if fmt
                      (propertize (format fmt line-number) 'face 'linum)
                    (funcall linum-format line-number)))
             (visited (catch 'visited
                        (dolist (o (overlays-in (point) (point)))
                          (when (string= (overlay-get o 'linum-str) str)
                            (unless (memq o linum-overlays)
                              (push o linum-overlays))
                            (setq linum-available (delete o linum-available))
                            (throw 'visited t))))))
        (setq width (max width (length str)))
        (unless visited
          (let ((ov (if (null linum-available)
                        (make-overlay (point) (point))
                      (move-overlay (pop linum-available) (point) (point)))))
            (push ov linum-overlays)
            (overlay-put ov 'before-string
                         (propertize " " 'display `((margin left-margin) ,str)))
            (overlay-put ov 'linum-str str))))
      (forward-line)
      (setq line (1+ line)))
    (set-window-margins win width)))
</code></pre>

<p>And then finally, in your <code>.emacs</code> file somewhere, turn on this new setting.</p>

<pre><code>(setq linum-offset t)
</code></pre>

<p>There you go, I hope you find it as useful as I have.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/10/better-line-numbering-in-emacs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Problems with Time</title>
		<link>http://www.overwatering.org/blog/2011/03/the-problems-with-time/</link>
		<comments>http://www.overwatering.org/blog/2011/03/the-problems-with-time/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 11:26:24 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[comp. sci.]]></category>
		<category><![CDATA[time is on your side]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=373</guid>
		<description><![CDATA[As all programmers know, there are serious problems with the way our society has chosen to divide up time. As an example, right now it is 9:44pm on Monday, 21 March 2011. Quick, what is the date and time in one month, five days, eight hours, 23 minutes and 45 seconds.

I&#8217;m sure you&#8217;ve all worked [...]]]></description>
			<content:encoded><![CDATA[<p>As all programmers know, there are serious problems with the way our society has chosen to divide up time. As an example, right now it is 9:44pm on Monday, 21 March 2011. Quick, what is the date and time in one month, five days, eight hours, 23 minutes and 45 seconds.</p>

<p>I&#8217;m sure you&#8217;ve all worked that out by now. It&#8217;s not actually hard, but it is labourious. And it is hard to do that programmatically for arbitrary time periods.</p>

<p>Compare to the following. Here&#8217;s 15kg and 400g of flour. How much flour if you add 2 tons, 67kg and 700g? Much easier right? Also much easier to do programmatically. This is the beauty of the metric system.</p>

<p>So let&#8217;s metricise time.</p>

<p>There are only two periods that are fixed in length: the year, and the day. All other divisions can be whatever we want them to be.</p>

<p>So working back from the year and the day, here&#8217;s my modest proposal for the metrication of time:</p>

<ul>
<li>Each year will be exactly 360 days long. The remaining five days will not be part of a year: instead this gap will become the mid-summer (or winter) festival. Coinciding with what is currently the week between Christmas and New Year&#8217;s Day. Any leap days or seconds will be included in this period. Every four years the festival will be six days long.</li>
<li>The year will be divided into 36 ten day long weeks.</li>
<li>These weeks can be further collected into all sorts of other periods: 90 days for a quarter — which would be nine weeks — and a month would be 30 days, or three weeks. All very straight forward to convert between.</li>
<li>And there would still be twelve months in a year.</li>
<li>Each day would have 10 hours, with 100 minutes per hour and 100 seconds per minute. Which would make the metric second equal 0.864 &#8216;imperial&#8217; seconds.</li>
</ul>

<p>And this is where we hit the last remaining, apparently insurmountable, problem of time. The <a href="http://en.wikipedia.org/wiki/Second">second</a> is an <a href="http://en.wikipedia.org/wiki/International_System_of_Units">SI</a> unit. And a fundamental one at that.</p>

<p>Changing the definition of a second, especially by that much, would make existing scientific results confusing and misleading to work with.</p>

<div style="float:right; width: 40%; font-size: 0.7em; padding: 5px; line-height: 1.45em; margin: 5px; background-color: rgb(204, 204, 255)">
Time zones are a good thing. With time zones I can convert my time into the time in some other part of the world and instantly have an idea as to what people there are probably up to. Without time zones I would require a lookup table to determine that information. And that would be an inconvenient lookup table.
</div>

<p>But this last remaining problem can also be solved easily: use a different name. When weights went metric the ounce and pound weren&#8217;t re-named, new names were introduced. SI can retain the current base unit of time as the second, while the metric unit will be known as something else. And as it is so easy to convert between metric units of time, all that needs to be done is convert a metric time into base units, and then convert those to seconds. Ta da!</p>

<p>There will be the small problem of mapping pre-metric dates to metric dates. But I&#8217;m sure we can work something out. Perhaps a grand re-labelling?</p>

<p>Ultimately, our current system of sub-dividing time is painfully inconvenient. Do you really think that we&#8217;re going to keep it forever? Or, do you think we&#8217;ll need a complete societal collapse to replace? I think we can do better than both those options.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/03/the-problems-with-time/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>M&amp;Ms</title>
		<link>http://www.overwatering.org/blog/2011/03/mms/</link>
		<comments>http://www.overwatering.org/blog/2011/03/mms/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 09:38:20 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[internet event horizon]]></category>
		<category><![CDATA[m&m]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=371</guid>
		<description><![CDATA[&#8220;Please use this M&#38;M for breeding purposes.&#8221; I am certain that is older than 2007. But thanks to the Internet Event Horizon, that&#8217;s where Google tells me it is from. Does anyone out there know where this originated?

There should be credit where credit is due.
]]></description>
			<content:encoded><![CDATA[<p>&#8220;Please use this M&amp;M for breeding purposes.&#8221; I am certain that is older than 2007. But thanks to the Internet Event Horizon, that&#8217;s where Google tells me it is from. Does anyone out there know where this originated?</p>

<p>There should be credit where credit is due.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/03/mms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Patterns for Bundler and rvm</title>
		<link>http://www.overwatering.org/blog/2011/03/patterns-for-bundler-and-rvm/</link>
		<comments>http://www.overwatering.org/blog/2011/03/patterns-for-bundler-and-rvm/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 11:49:25 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[ruby bundler rvm]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=367</guid>
		<description><![CDATA[A couple of long standing problems in the world of Ruby have been dealing with all the gems that are so easy to toss into your project and the differences between Ruby implementations. They do differ: between 1.8.6 and 1.8.7 standard library APIs changed. Slow clap.

In the world of adults the solution to these problems [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of long standing problems in the world of Ruby have been dealing with all the gems that are so easy to toss into your project and the differences between Ruby implementations. They do differ: between 1.8.6 and 1.8.7 standard library APIs changed. Slow clap.</p>

<p>In the world of adults the solution to these problems is known as dependency management. There are now two tools to help Ruby: <a href="http://rvm.beginrescueend.com">rvm</a> and <a href="http://gembundler.com">Bundler</a>. These are both opinionated pieces of software that try to do a lot to help. Often far too much. After digging quite deeply into Bundler with <a href="http://pilchardfriendly.wordpress.com/">Nick Drew</a> on a recent project, here are some things that we learnt that I&#8217;ve tried to distill into a set of guides on good ways to use Bundler and rvm. This is just what I&#8217;ve discovered, if there are any tips or better ways to use these tools, or other tools that help, please share.</p>

<p>This is going to assume that you already know something about both.</p>

<ul>
<li>Firstly, use rvm and Bundler. If you have used them in the past and were unhappy, try again. The early versions had some truly horrible bugs. Development has moved quickly and things are a lot better now. If you&#8217;re using Rails 3 then you have little choice about Bundler. But for any projects you should use these.</li>
<li>Use rvm to install your Ruby, don&#8217;t use the system Ruby. Create at least one gemset and use that.</li>
<li><p>Create a <code>.rvmrc</code> for your project and check it into source control. Naming the gemset after your project, it should probably look something like:</p>

<pre><code>rvm_install_on_use_flag=1
rvm --create use ruby-1.8.7-p330@project
</code></pre></li>
<li><p>Use rvm on your build box. But not in production.</p></li>
<li>Create a <code>personal</code> gem set and toss the gems you use on simple little scripts into that.</li>
<li>Install Bundler into the global gemset for the Ruby you are using.</li>
<li>Include <code>development</code> and <code>test</code> groups in your <code>Gemfile</code>. Be strict about the difference between a gem required to run the build system (development), used in tests (test — obviously) and a gem required to run the application.</li>
<li>Don&#8217;t check the <code>.bundle/config</code> file into source control. Bundler often chooses to remember settings in this file. This will cause much irritation. This is an example of being more helpful than is helpful.</li>
<li>Don&#8217;t use the <code>--deployment</code> switch to <code>bundle install</code> unless you really mean that. As well as producing a local bundle of gems, installing in deployment mode will freeze the Gemfile. This is remembered and will cause much frustration when you&#8217;re trying to add new gems. If this does happen you will get an opaque error complaining that you have not checked your <code>Gemfile.lock</code> into source control. To get around this, just delete your <code>.bundle/config</code>. You&#8217;re doing that to remove the remembered setting about freezing your gems.</li>
<li><p>Your build script (the one you run before committing) should call <code>bundle package</code>. In fact, it should look quite a lot like:</p>

<pre><code>bundle package &amp;&amp; bundle install &amp;&amp; rake spec features
</code></pre></li>
<li><p>Check the gem files in <code>vendor/cache</code> into source control.</p></li>
<li>Definitely use <code>bundle install --deployment --local --without="development test"</code> either as part of your Capistrano tasks or as part of packaging for a release. Every one of those switches except the first should not be required. But they are. So there you go.</li>
<li>Bundler attempts to take over your world. This is intensely irritating. Expect to be annoyed.</li>
<li><p>If you ever need to start a Ruby program from your Ruby program but in a different Bundler world, you will need to do some cleaning of your environment. In particular you will need to clean the environment variables <code>BUNDLE_GEMFILE</code>, <code>BUNDLE_PATH</code>, <code>BUNDLE_BIN_PATH</code> and most surprisingly <code>RUBYOPT</code>. You may find the following function helpful.</p>

<pre><code>def without_bundler_env
  original_env = ENV.to_hash
  ENV.delete("BUNDLE_GEMFILE")
  ENV.delete("BUNDLE_PATH")
  ENV.delete("BUNDLE_BIN_PATH")
  ENV.delete("RUBYOPT")
  yield
ensure
  ENV.replace(original_env.to_hash)
end
</code></pre></li>
<li><p>If you need to examine the <code>Gemfile</code> from another Ruby project in your Bundler controlled world, you will think that you can use <code>Bundler::Definition.build("&lt;i&gt;path to Gemfile&lt;/i&gt;", "&lt;i&gt;path to Gemfile.lock&lt;/i&gt;", nil)</code>. That would be a good start. You will also need to set <code>ENV["BUNDLE_GEMFILE"]</code> to point to that file and call <code>resolve_with_cache!</code>, however. Try the following:</p>

<pre><code>ENV['BUNDLE_GEMFILE'] = 'Gemfile'
bundle_def = Bundler::Definition.build('Gemfile',
                                       'Gemfile.lock',
                                       nil)
bundle_def.resolve_with_cache!
</code></pre></li>
</ul>

<p>Ultimately, the goal of Bundler and rvm are noble. Dependency management is a hard problem. And there are no alternatives if you are choosing to use Ruby. Are there things that could perhaps be done better? Absolutely. But there is probably nothing so bad that some patterns couldn&#8217;t fix. So please, let&#8217;s all work out how to get the most out of these tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2011/03/patterns-for-bundler-and-rvm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why WikiLeaks Matters</title>
		<link>http://www.overwatering.org/blog/2010/12/why-wikileaks-matters/</link>
		<comments>http://www.overwatering.org/blog/2010/12/why-wikileaks-matters/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 13:15:19 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[politics]]></category>
		<category><![CDATA[wikileaks]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=365</guid>
		<description><![CDATA[Much, but refreshingly not all, of the arguments about WikiLeaks have focussed on whether or not WikiLeaks was right to leak those diplomatic cables. Do governments have the right to private conversations? Individuals do, so why not governments? And if governments do, then what about corporations? Well, I believe all those arguments are missing the [...]]]></description>
			<content:encoded><![CDATA[<p>Much, but refreshingly not all, of the arguments about WikiLeaks have focussed on whether or not WikiLeaks was right to leak those diplomatic cables. Do governments have the right to private conversations? Individuals do, so why not governments? And if governments do, then what about corporations? Well, I believe all those arguments are missing the point. Because, information wants to be free.</p>

<p>&#8220;Information wants to be free&#8221; is not a position. Information wants to be free in the same way that <a href="http://www.jwz.org/doc/iwtbf.html">nature abhors a vacuum</a>. It is simply a statement of the default state of affairs: information that can be reproduced perfectly and cheaply will be reproduced.</p>

<p>WikiLeaks is simply the natural result of a network and technology that has evolved to be really good at that reproduction. To me this means that questions of who owns the information, is government information different from corporate information, and should this affect individuals&#8217; attitudes towards WikiLeaks are all slightly beside the point.</p>

<p>To repeat a tired cliché, the genie is well and truly out of the bottle: the technology to allow massive and anonymous leaks is now here for everyone. These kinds of leaks will only become more common. Irrespective of what happens to WikiLeaks and Julian Assange.</p>

<p>Unless something very draconian and totalitarian is done.</p>

<p>Which is why I don&#8217;t bother thinking about whether or not I personally agree with WikiLeaks (though I do), instead I worry about what the end result of attempts to shut it down will look like. That future police state is what we need to fight.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2010/12/why-wikileaks-matters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

