<?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 &#187; computing</title>
	<atom:link href="http://www.overwatering.org/blog/category/computing/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>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>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>
		<item>
		<title>Toys, Tools &amp; Petrie Dishes</title>
		<link>http://www.overwatering.org/blog/2010/11/toys-tools-petrie-dishes/</link>
		<comments>http://www.overwatering.org/blog/2010/11/toys-tools-petrie-dishes/#comments</comments>
		<pubDate>Sun, 21 Nov 2010 11:14:57 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[comp. sci.]]></category>
		<category><![CDATA[computing]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=354</guid>
		<description><![CDATA[In my opinion there are three kinds of programming language.


Toys: Languages that were designed by one person to scratch an itch or serve particular purpose, no more. Ruby was designed by Matz for programmer happiness. C was designed by Ritchie so he could port that Space Invaders OS to a different machine than the PDP/10.
Petrie [...]]]></description>
			<content:encoded><![CDATA[<p>In my opinion there are three kinds of programming language.</p>

<ul>
<li><em>Toys</em>: Languages that were designed by one person to scratch an itch or serve particular purpose, no more. Ruby was designed by Matz for programmer happiness. C was designed by Ritchie so he could port that Space Invaders OS to a different machine than the PDP/10.</li>
<li><em>Petrie Dishes</em>: Usually designed in academia as a language to experiment with language design ideas. Haskell was designed to be the canonical lazy, pure functional language. Scala is an experiment in type systems.</li>
<li><em>Tools</em>: Designed for serious business, dammit. These are meant to be used to build big important pieces of code. C++ evolved from C for better simulation implementations. Java was an easy to learn language for portable binaries.</li>
</ul>

<p>Like biology and all other taxonomies, this is of course a flawed generalisation. It&#8217;s also incomplete. I know that Perl 5 is a toy, but what&#8217;s Perl 6 (apart from vapour)? Is it a tool? Or something else entirely?</p>

<p>Setting aside these issues, I have a personal statement. I want to learn and learn from Petrie Dishes; I want to use Toys for my day to day work and experimentation; I want to stay as far away from Tools as I can manage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2010/11/toys-tools-petrie-dishes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Links in Tweets</title>
		<link>http://www.overwatering.org/blog/2009/04/links-in-tweets/</link>
		<comments>http://www.overwatering.org/blog/2009/04/links-in-tweets/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 03:43:54 +0000</pubDate>
		<dc:creator>giles</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.overwatering.org/blog/?p=149</guid>
		<description><![CDATA[There is currently some discussion about the dangers of URL shorteners. Joshua Schachter points out that shortened URLs damage the web &#8211; the &#8216;hypertext as engine of application state&#8217; part of it. David Weiss points out the security concerns &#8211; phishing and a single compromisable point.

In this conversation most people point out that URL shorteners [...]]]></description>
			<content:encoded><![CDATA[<p>There is currently some discussion about the dangers of URL shorteners. <a href="http://joshua.schachter.org/2009/04/on-url-shorteners.html">Joshua Schachter</a> points out that shortened URLs damage the web &#8211; the &#8216;hypertext as engine of application state&#8217; part of it. <a href="http://unweary.com/2009/04/the-security-implications-of-url-shortening-services.html">David Weiss</a> points out the security concerns &#8211; phishing and a single compromisable point.</p>

<p>In this conversation most people point out that URL shorteners have proliferated because of the popularity of <a href="http://twitter.com">Twitter</a>. <a href="http://www.kottke.org/09/04/url-shorteners-suck">Kottke</a> has now proposed that Twitter run a URL shortener of their own. Which seems eminently sensible, given the current state.</p>

<p>I&#8217;ve got a different suggestion: Twitter should actually let me use the <code>&lt;a&gt;</code> anchor tag in my tweets. Just like I&#8217;ve been doing in HTML for as long as the web has been around. That is, the URL in your tweet should not contribute to the number of characters in your tweet, and it should also not be visible. Instead it should be attached to a word, phrase or perhaps the entire tweet. This should be optional: without markup URLs pasted into tweets should maintain the status quo.</p>

<p>Of course, no other forms of HTML markup should be supported: linking would be enough. The Twitter web site and desktop and custom phone clients would have no problem rendering a link. Only SMS clients would have a problem, and for these perhaps the fallback is to shorten the URL using Twitter&#8217;s own URL shortener and insert that into the tweet. SMS clients may not be that <a href="http://www.neoformix.com/2008/TwitterClientUsage.html">common</a> for much longer.</p>

<p>Assuming Twitter allows specific parts of the tweet to be marked up, then I suggest <a href="http://daringfireball.net/projects/markdown/">Markdown</a> syntax for the link. <a href="https://twitter.com/gga/status/1454868052">This recent tweet</a> would have been typed out as:</p>

<pre><code>I unplugged every landline phone in our office
because of [marketers](http://sethgodin.typepad.com/seths_blog/2009/04/poisoning-the-well.html) (via @misswired)
</code></pre>

<p>Which would have appeared as:</p>

<blockquote>
  <p>I unplugged every landline phone in our office because of <a href="http://sethgodin.typepad.com/seths_blog/2009/04/poisoning-the-well.html">marketers</a> (via <a href="http://twitter.com/misswired">@misswired</a>)</p>
</blockquote>

<p>Which is what I was actually trying to say.</p>

<p>Of course allowing link markup like this is going to be very popular with spammers. Two counters:</p>

<ol>
<li>Twitter should include <code>rel="nofollow"</code> on links when rendering &#8211; as they already do.</li>
<li>Don&#8217;t allow targeted markup like this, instead allow the entire Tweet to be marked up &#8211; only one link per tweet. The disadvantage with this is that sometimes I want more than one link, and the appropriate rendering is not obvious.</li>
</ol>

<p>Both targeted markup and one-link-per-tweet have advantages and disadvantages, I&#8217;ll leave it up to Twitter to choose between them. But please, give me back my <code>&lt;a&gt;</code> anchors.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.overwatering.org/blog/2009/04/links-in-tweets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

