Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: hnrysmth/henrysmith.org
base: 17d3c629a1
...
head fork: hnrysmth/henrysmith.org
compare: 442c95cc9a
Checking mergeability… Don't worry, you can still create the pull request.
  • 6 commits
  • 44 files changed
  • 0 commit comments
  • 1 contributor
Showing with 17 additions and 8,950 deletions.
  1. +1 −0  .gitignore
  2. +7 −0 Rakefile
  3. +1 −1  _posts/2013-11-03-devils-dictionary-of-programming.md
  4. +1 −1  _posts/2013-12-26-mobile-computing-research-is-a-hornets-nest-of-deception-and-chicanery.md
  5. +7 −0 _posts/2014-01-26-it-takes-time.md
  6. +0 −211 _site/blog/active-record-as-a-database-cli/index.html
  7. +0 −107 _site/blog/all-your-code-should-help/index.html
  8. +0 −142 _site/blog/code-i-like-twig-loaders/index.html
  9. +0 −179 _site/blog/debian-squeeze-vagrant-base-box/index.html
  10. BIN  _site/blog/decoupling-nested-backbone-views/lines.png
  11. BIN  _site/blog/decoupling-nested-backbone-views/list.gif
  12. BIN  _site/blog/decoupling-nested-backbone-views/map.gif
  13. +0 −173 _site/blog/dont-use-requirejs-as-a-service-locator/index.html
  14. +0 −2,579 _site/blog/feed.xml
  15. +0 −153 _site/blog/frontend-finite-state-machines/index.html
  16. +0 −107 _site/blog/i-should-never-build-a-time-machine/index.html
  17. +0 −310 _site/blog/index.html
  18. +0 −123 _site/blog/monkey-patches-broke-my-build/index.html
  19. +0 −154 _site/blog/more-on-finite-state-machines/index.html
  20. BIN  _site/blog/more-on-finite-state-machines/states.png
  21. +0 −131 _site/blog/null/index.html
  22. +0 −220 _site/blog/ppls-design/index.html
  23. +0 −136 _site/blog/rollercoaster-code/index.html
  24. +0 −121 _site/blog/scrutinizer-ci-code-climate-for-php/index.html
  25. BIN  _site/blog/scrutinizer-ci-code-climate-for-php/screenshot.png
  26. +0 −195 _site/blog/switch-true/index.html
  27. +0 −184 _site/blog/ternary-abuse/index.html
  28. BIN  _site/blog/tescos-self-checkout-traffic-lights/crazy.gif
  29. BIN  _site/blog/tescos-self-checkout-traffic-lights/fixed.gif
  30. +0 −151 _site/blog/tescos-self-checkout-traffic-lights/index.html
  31. BIN  _site/blog/tescos-self-checkout-traffic-lights/normal.gif
  32. +0 −103 _site/blog/the-mythical-one-off-script/index.html
  33. +0 −393 _site/blog/whitespace-sins/index.html
  34. +0 −458 _site/blog/whitespace-sins/style.css
  35. +0 −119 _site/blog/xkcd-1288-and-tdd/index.html
  36. +0 −122 _site/blog/yes-you-need-timestamps/index.html
  37. BIN  _site/images/profile.jpg
  38. BIN  _site/images/whitespace-sins/fig.png
  39. BIN  _site/images/whitespace-sins/sloth.png
  40. +0 −196 _site/index.html
  41. +0 −896 _site/links/feed.xml
  42. +0 −986 _site/links/index.html
  43. +0 −1  _site/stylesheets/foundation/foundation.min.css
  44. +0 −298 _site/stylesheets/henrysmith/8.css
View
1  .gitignore
@@ -1 +1,2 @@
.vagrant/
+_site
View
7 Rakefile
@@ -6,6 +6,13 @@ task :default => [:all]
task :all => [:css, :html]
+task :deploy do
+ dot_git = File.expand_path(File.join(File.dirname(__FILE__), ".git"))
+ system "git --git-dir #{dot_git} pull origin master"
+ system "bundle install"
+ system "bundle exec jekyll build"
+end
+
task :css do
version = config("version")
root = File.dirname(__FILE__)
View
2  _posts/2013-11-03-devils-dictionary-of-programming.md
@@ -1,5 +1,5 @@
---
-title: Devils Dictionary of Programming
+title: Devil's Dictionary of Programming
date: 2013-11-03
category: link
link: http://programmingisterrible.com/post/65781074112/devils-dictionary-of-programming
View
2  _posts/2013-12-26-mobile-computing-research-is-a-hornets-nest-of-deception-and-chicanery.md
@@ -1,5 +1,5 @@
---
-title: Mobile Computing Research Is A Hornets Nest Of Deception And Chicanery
+title: Mobile Computing Research Is A Hornet's Nest Of Deception And Chicanery
link: http://research.microsoft.com/en-us/people/mickens/nestofhornets.pdf
date: 2013-12-26
category: link
View
7 _posts/2014-01-26-it-takes-time.md
@@ -0,0 +1,7 @@
+---
+title: It Takes Time
+link: http://mattduvall.com/blog/it-takes-time/
+date: 2014-01-26
+category: link
+permalink: /
+---
View
211 _site/blog/active-record-as-a-database-cli/index.html
@@ -1,211 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Active Record As A Database CLI</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Active Record As A Database CLI
- </h1>
- </header>
- <p>The combination of Active Record and Active Support in <code>rails console</code> is such a
-nice way of interacting with a database on the command-line that I&#39;ve often
-myself wanting to use it everywhere, including projects that don&#39;t otherwise use
-Rails or even Ruby at all.</p>
-
-<p>This seems like an obvious idea, so when I eventually got around to setting it
-up for the enormous schema I interact with daily at work, I was surprised at the
-lack of search results I could dig up on the topic. Either nobody else is doing
-this, or they&#39;re not talking about it, or I just did a really bad job of
-searching. Whatever the case may be, here&#39;s what I&#39;m talking about and why I
-think it&#39;s great.</p>
-
-<h2>An Active Record CLI For Your Database</h2>
-
-<p>The basic principle is to use Active Record as an alternative to your database&#39;s
-own plain SQL command-line interface such as the <code>psql</code> command of Postgres.</p>
-<div class="highlight"><pre><code class="text">example=# select * from products where id = 1;
- id | name
-----+----------------
- 1 | Electric Drill
-(1 row)
-</code></pre></div>
-<p>Instead, you load up Active Record into a Ruby REPL and query the database
-through that. It&#39;s a lot like the interface you get in <code>bundle exec rails
-console</code>, but without the rest of the Rails project underneath it.</p>
-<div class="highlight"><pre><code class="ruby"><span class="o">&gt;</span> <span class="no">Product</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="ss">:id</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">)</span>
-<span class="o">=&gt;</span> <span class="c1">#&lt;ActiveRecord::Relation [#&lt;Product id: 1, name: &quot;Electric Drill&quot;]&gt;]&gt;</span>
-</code></pre></div>
-<h2>Why This is Great</h2>
-
-<h4>Assign A Row To A Variable</h4>
-
-<p>One of the most tedious things about your typical database CLI is repeatedly
-re-entering the same <code>WHERE id = 1234</code> clause in every query during prolonged
-interaction with a particular row of interest. One of the benefits of using Ruby
-instead is that you can put that row in a variable and save your fingers.</p>
-<div class="highlight"><pre><code class="ruby"><span class="o">&gt;</span> <span class="n">drill</span> <span class="o">=</span> <span class="no">Product</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="ss">:id</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
-<span class="o">=&gt;</span> <span class="c1">#&lt;Product id: 1, name: &quot;Electric Drill&quot;]&gt;</span>
-<span class="o">&gt;</span> <span class="n">drill</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Power Drill&quot;</span>
-<span class="o">=&gt;</span> <span class="s2">&quot;Power Drill&quot;</span>
-<span class="o">&gt;</span> <span class="n">drill</span><span class="o">.</span><span class="n">save</span>
-<span class="o">=&gt;</span> <span class="kp">true</span>
-</code></pre></div>
-<h4>Easy Relation Traversal</h4>
-
-<p>When examining a given database row, I often find that I need to find out
-information about its related rows. The Active Record approach to this is
-usually both the quickest <em>and</em> the laziest way to get the answers I need.</p>
-<div class="highlight"><pre><code class="ruby"><span class="o">&gt;</span> <span class="n">drill</span><span class="o">.</span><span class="n">purchases</span><span class="o">.</span><span class="n">count</span>
-<span class="o">=&gt;</span> <span class="mi">29</span>
-<span class="o">&gt;</span> <span class="n">drill</span><span class="o">.</span><span class="n">purchases</span><span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="s1">&#39;created ASC&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">name</span>
-<span class="o">=&gt;</span> <span class="s2">&quot;Adam Smith&quot;</span>
-</code></pre></div>
-<h4>Active Support Date Manipulation</h4>
-
-<p>One of the most tedious and error-prone common tasks involving database rows is
-the modification of timestamps. If I&#39;m modifying timestamps, it usually means
-I&#39;m trying to reproduce some very specific piece of the system&#39;s behaviour. For
-example, &quot;Send the user an email seven days after signing up&quot;, or &quot;Extend the
-user&#39;s subscription by three weeks&quot;. Doing date arithmetic in SQL makes me sad,
-and one of the main reasons I&#39;ll spin up my Active Record CLI gem is to avoid
-it.</p>
-<div class="highlight"><pre><code class="ruby"><span class="o">&gt;</span> <span class="n">user</span><span class="o">.</span><span class="n">registered_at</span> <span class="o">=</span> <span class="mi">7</span><span class="o">.</span><span class="n">days</span><span class="o">.</span><span class="n">ago</span>
-<span class="o">=&gt;</span> <span class="no">Sat</span><span class="p">,</span> <span class="mi">25</span> <span class="no">Feb</span> <span class="mi">2012</span> <span class="mi">15</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">45</span> <span class="no">UTC</span> <span class="o">+</span><span class="mo">00</span><span class="p">:</span><span class="mo">00</span>
-<span class="o">&gt;</span> <span class="n">user</span><span class="o">.</span><span class="n">subscription</span><span class="o">.</span><span class="n">expiry_date</span> <span class="o">+=</span> <span class="mi">3</span><span class="o">.</span><span class="n">weeks</span>
-<span class="o">=&gt;</span> <span class="no">Sat</span><span class="p">,</span> <span class="mi">10</span> <span class="no">Mar</span> <span class="mi">2012</span> <span class="mi">15</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">45</span> <span class="no">UTC</span> <span class="o">+</span><span class="mo">00</span><span class="p">:</span><span class="mo">00</span>
-</code></pre></div>
-<h2>Why It&#39;s Not Great</h2>
-
-<p>There are some considerable downsides when building and using an Active Record
-gem to interact with your database. The main annoyance is the fact that you have
-to take the time to define a bunch of model classes representing your database
-schema. Chances are, your schema won&#39;t follow Active Record&#39;s conventions as
-much as a typical Rails project, so you might find you have to write 10 lines or
-more of Ruby code per entity.</p>
-<div class="highlight"><pre><code class="ruby"><span class="k">class</span> <span class="nc">Customer</span> <span class="o">&lt;</span> <span class="ss">ActiveRecord</span><span class="p">:</span><span class="ss">:Base</span>
- <span class="nb">self</span><span class="o">.</span><span class="n">table_name</span> <span class="o">=</span> <span class="s2">&quot;acme_customer&quot;</span>
-
- <span class="n">has_many</span> <span class="ss">:purchases</span><span class="p">,</span> <span class="p">{</span>
- <span class="ss">:primary_key</span> <span class="o">=&gt;</span> <span class="ss">:id</span><span class="p">,</span>
- <span class="ss">:foreign_key</span> <span class="o">=&gt;</span> <span class="ss">:user_id</span><span class="p">,</span>
- <span class="p">}</span>
-
- <span class="n">has_many</span> <span class="ss">:products</span><span class="p">,</span> <span class="ss">:through</span> <span class="o">=&gt;</span> <span class="ss">:purchases</span>
-<span class="k">end</span>
-</code></pre></div>
-<p>This is doubly problematic, because schemas change over time, and so these
-<code>ActiveRecord::Base</code> subclasses must be maintained and kept synchronised.</p>
-
-<p>I also find that the suitability of Active Record for a given database-related
-task is quite variable. A lot of the time, it&#39;s much, much better to open a
-plain SQL prompt. It&#39;s only in certain cases, such as those described above,
-that I reach for this tool.</p>
-
-<h2>How To Set This Up</h2>
-
-<p>Getting this running involves creating a small Ruby gem. The one I use at work
-is a total of 27 files and 257 lines of code. Apart from all the
-<code>ActiveRecord::Base</code> subclasses, the other important file is <a href="https://github.com/h2s/exampledb/blob/master/bin/exampledb">the one that sets
-everything up</a> and
-hands over control to the user.</p>
-
-<h4>OptionParser</h4>
-
-<p>Unless you want to store database credentials in plain text somewhere in your
-gem (no), you&#39;ll need something resembling the typical SQL prompt&#39;s option
-parsing capabilities.</p>
-<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s2">&quot;optparse&quot;</span>
-<span class="n">options</span> <span class="o">=</span> <span class="p">{}</span>
-<span class="no">OptionParser</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="n">parser</span><span class="o">|</span>
- <span class="n">parser</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;-h&quot;</span><span class="p">,</span> <span class="s2">&quot;--hostname [HOSTNAME]&quot;</span><span class="p">,</span> <span class="nb">String</span><span class="p">,</span> <span class="ss">:required</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">hostname</span><span class="o">|</span>
- <span class="n">options</span><span class="o">[</span><span class="ss">:hostname</span><span class="o">]</span> <span class="o">=</span> <span class="n">hostname</span>
- <span class="k">end</span>
- <span class="n">parser</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;-d&quot;</span><span class="p">,</span> <span class="s2">&quot;--database [DATABASE]&quot;</span><span class="p">,</span> <span class="nb">String</span><span class="p">,</span> <span class="ss">:required</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">database</span><span class="o">|</span>
- <span class="n">options</span><span class="o">[</span><span class="ss">:database</span><span class="o">]</span> <span class="o">=</span> <span class="n">database</span>
- <span class="k">end</span>
- <span class="n">parser</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;-u&quot;</span><span class="p">,</span> <span class="s2">&quot;--username [USERNAME]&quot;</span><span class="p">,</span> <span class="nb">String</span><span class="p">,</span> <span class="ss">:required</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">username</span><span class="o">|</span>
- <span class="n">options</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span> <span class="o">=</span> <span class="n">username</span>
- <span class="k">end</span>
- <span class="n">parser</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="s2">&quot;-p&quot;</span><span class="p">,</span> <span class="s2">&quot;--password [PASSWORD]&quot;</span><span class="p">,</span> <span class="nb">String</span><span class="p">,</span> <span class="ss">:required</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">password</span><span class="o">|</span>
- <span class="n">options</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span> <span class="o">=</span> <span class="n">password</span>
- <span class="k">end</span>
-<span class="k">end</span><span class="o">.</span><span class="n">parse!</span>
-</code></pre></div>
-<h4>Active Record</h4>
-
-<p>Next, take the freshly-parsed <code>options</code> hash and use it to warm up your Active
-Record database connection.</p>
-<div class="highlight"><pre><code class="ruby"><span class="ss">ActiveRecord</span><span class="p">:</span><span class="ss">:Base</span><span class="o">.</span><span class="n">establish_connection</span><span class="p">({</span>
- <span class="ss">:adapter</span> <span class="o">=&gt;</span> <span class="s2">&quot;mysql2&quot;</span><span class="p">,</span>
- <span class="ss">:host</span> <span class="o">=&gt;</span> <span class="n">options</span><span class="o">[</span><span class="ss">:hostname</span><span class="o">]</span><span class="p">,</span>
- <span class="ss">:database</span> <span class="o">=&gt;</span> <span class="n">options</span><span class="o">[</span><span class="ss">:database</span><span class="o">]</span><span class="p">,</span>
- <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">options</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">,</span>
- <span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">options</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span>
-<span class="p">})</span>
-</code></pre></div>
-<h4>Start A REPL</h4>
-
-<p>To hand over control to the user, we need to launch a REPL. I use
-<a href="https://github.com/pry/pry">Pry</a> for this, as it offers a great deal of
-flexibility.</p>
-<div class="highlight"><pre><code class="ruby"><span class="nb">require</span> <span class="s2">&quot;pry&quot;</span>
-<span class="no">Pry</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">prompt</span> <span class="o">=</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">obj</span><span class="p">,</span> <span class="n">nest_level</span><span class="p">,</span> <span class="n">_</span><span class="o">|</span> <span class="s2">&quot;&gt; &quot;</span> <span class="p">}</span>
-<span class="no">Pry</span><span class="o">.</span><span class="n">start</span>
-</code></pre></div>
-<h2>Give It A Try</h2>
-
-<p>Getting this running was a few hours&#39; worth of time investment for me, and six
-months later it remains something I use almost every day. For anyone interested
-in trying it out on their own project, I&#39;ve prepared an <a href="https://github.com/h2s/exampledb">example project</a> that
-sets up everything for you so you can get started in a few minutes by editing
-some model classes and installing your gem. So if you&#39;re curious, go <a href="">fork it
-now</a>!</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2013-09-21" pubdate="pubdate">
- SEP 21 2013
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
107 _site/blog/all-your-code-should-help/index.html
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>All Your Code Should "Help"</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- All Your Code Should "Help"
- </h1>
- </header>
- <p>Programmers sometimes designate a piece of code a &quot;helper class&quot; or &quot;helper
-function&quot;, and I think this is problematic in a couple of ways. The purpose of
-all code is to &quot;help&quot; complete a task, so to single out any particular piece of
-code and call it a &quot;helper&quot; is at best uninsightful naming, and at worst an
-architectural <a href="http://www.unclebobs.com/getstorganized/index.php/eliminate-the-junk-drawer/">junk drawer</a>.</p>
-
-<h2>Uninsightful Naming</h2>
-
-<p>Rails apps come with an <code>app/helpers</code> directory built in. The term &quot;helper&quot; has
-a very specific meaning in Rails, and only logic relating to the view is
-supposed to reside here. Sometimes these view helpers can get out of hand, but
-there is lots of great advice out there for <a href="http://railscasts.com/episodes/101-refactoring-out-helper-object">refactoring and cleaning them up</a>, and I think the concept itself is sound.</p>
-
-<p>The problem with them is just the choice of name. When you run <code>rails new</code> for
-the first time, and you look in that bare <code>app/helpers</code> directory, its purpose
-is completely unclear. The documentation doesn&#39;t contain any concise statement
-explaining the intended usage of &quot;helpers&quot;. You pretty much have to pick it
-up like a piece of tribal knowledge by noticing that whenever anybody talks
-about &quot;helpers&quot;, they are always talking about output generation.</p>
-
-<p>Names are a great way of communicating the nature or purpose of something. They
-are better than comments or documentation. In Rails&#39; case, the name choice of
-&quot;helpers&quot; is uninsightful, and therefore confusing to newcomers. A better
-alternative might have been <code>app/view_functions</code>, which is very ugly but has the
-distinct advantage of actually containing information.</p>
-
-<h2>Architectural Junk Drawers</h2>
-
-<p>CodeIgniter has a great example of a <a href="https://github.com/EllisLab/CodeIgniter/tree/d4d80223ccef8fd3606f3a89d33afbfe95226bd8/system/helpers">helper junk drawer</a>.
-It contains code from all sorts of different levels of abstraction, from
-<a href="https://github.com/EllisLab/CodeIgniter/blob/d4d80223ccef8fd3606f3a89d33afbfe95226bd8/system/helpers/file_helper.php">filesystem access</a> to <a href="https://github.com/EllisLab/CodeIgniter/blob/d4d80223ccef8fd3606f3a89d33afbfe95226bd8/system/helpers/captcha_helper.php">generating captcha images</a>.</p>
-
-<p>The reason why I think this is less than ideal is that once the junk drawer
-exists, it&#39;s always tempting to stash new things in there rather than putting
-any serious consideration into where they <em>should</em> go. And if functions as
-disparate as <code>create_captcha</code> and <code>write_file</code> can go in your &quot;helpers&quot;
-directory, then what <em>can&#39;t</em> go in there?</p>
-
-<p>In the past I have been guilty of both initiating and contributing to this kind
-of IOU-driven design, and it&#39;s a dead end.</p>
-
-<h2>No Silver Bullet</h2>
-
-<p>There is no &quot;just do X instead&quot; alternative to helpers, except perhaps rational
-architecture and attentiveness when naming things. For me, the presence of the
-word &quot;helper&quot; is a red flag that immediately makes me wonder if I&#39;m about to
-open either a junk drawer or just a poorly-labelled one. Unless the system also
-contains code that <a href="http://thedailywtf.com/Articles/The-Speedup-Loop.aspx">deliberately hinders execution</a>, then
-&quot;helper&quot; is probably a bad label.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2013-05-19" pubdate="pubdate">
- MAY 19 2013
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
142 _site/blog/code-i-like-twig-loaders/index.html
@@ -1,142 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Code I Like: Twig Loaders</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Code I Like: Twig Loaders
- </h1>
- </header>
- <p>The <a href="http://twig.sensiolabs.org/">Twig templating library for PHP</a> is really quite a nice piece of
-software. In terms of external quality, it&#39;s stable, open source, actively
-maintained, and well documented. I&#39;ve been lucky enough to spend some time at
-work exploring its internals from time to time over the last 12 months or so,
-and I&#39;ve found the internal quality to be equally high. It&#39;s a pleasure to work
-with code that has been properly looked after.</p>
-
-<p>One particular aspect of Twig&#39;s design that I think exemplifies its internal
-quality is the way in which it loads template source code for compilation.
-There&#39;s more to it than just <code>file_get_contents</code>, and Twig manages that extra
-complexity well enough that it makes it look extremely simple.</p>
-
-<h2>The Hidden Complexity Of Template Loading</h2>
-
-<p>A first iteration of a very basic templating library would probably read
-template source code from a file on disk, like so.</p>
-<div class="highlight"><pre><code class="text">return file_get_contents(&quot;$templateName.twig&quot;);
-</code></pre></div>
-<p>A mature, general purpose library like Twig, on the other hand, needs to support
-its users&#39; diverse needs. Some people may not want to use the filesystem at all,
-because they may already have a string, or even an array of strings, ready for
-compilation. There&#39;s no getting away from this kind of complexity, so ideally it
-should be engaged head-on as a first class part of the design.</p>
-
-<h2>Successful Complexity Management In Twig</h2>
-
-<p>Twig rightly treats each different way of loading templates as a separate
-concern, with its own class implementing <a href="https://github.com/fabpot/Twig/blob/v1.13.1/lib/Twig/LoaderInterface.php"><code>Twig_LoaderInterface</code></a>. Filesystem
-interaction happens in <a href="https://github.com/fabpot/Twig/blob/v1.13.1/lib/Twig/Loader/Filesystem.php"><code>Twig_Loader_Filesystem</code></a>, while <a href="https://github.com/fabpot/Twig/blob/v1.13.1/lib/Twig/Loader/String.php"><code>Twig_Loader_String</code></a>
-serves the use-case of those who just want to compile from a string. These
-classes are absolutely tiny, and thus immediately comprehensible.</p>
-
-<p>As well as keeping Twig&#39;s own internal code clean, this approach provides a
-great deal of flexibility for anybody who needs bespoke template loading
-behaviour. Got some bizarre restriction forcing you to store templates in your
-database? Just write your own implementation of <code>Twig_LoaderInterface</code> and
-inject it into your <code>Twig_Environment</code> at instantiation.</p>
-
-<p>You can even chain loaders together using <a href="https://github.com/fabpot/Twig/blob/v1.13.1/lib/Twig/Loader/Chain.php"><code>Twig_Loader_Chain</code></a>. Need to fall
-back to your crazy database template storage only in the event that the file
-isn&#39;t found on disk? Add those two loaders in that order to a
-<code>Twig_Loader_Chain</code> and inject that into your <code>Twig_Environment</code>.</p>
-
-<p>Twig provides all this flexibility and makes it look easy, and it achieves this
-by a ruthless separation of concerns. It&#39;s a minor triumph of careful software
-design.</p>
-
-<h2>Failed Complexity Management In Smarty</h2>
-
-<p>This may seem like much ado about nothing. So Twig takes a relatively simple
-problem and makes it look simple, what&#39;s the big deal? It&#39;s a big deal to me
-because this kind of quality is actually surprisingly rare.</p>
-
-<p>As a counterexample, look at the approach taken by Twig&#39;s main competitor in the
-arena of PHP template libraries: <a href="http://www.smarty.net/">Smarty</a>. The Smarty equivalent to Twig&#39;s
-loaders all resides within <a href="https://github.com/TMSolution/smarty/blob/ecd289cab1f3687d9273eb401ef9bc807f706bbb/distribution/libs/sysplugins/smarty_internal_templatebase.php#L20-L361">one enormous &quot;fetch&quot; method</a>. It&#39;s
-300 lines of inflexible, incomprehensible <a href="/blog/rollercoaster-code">rollercoaster code</a>. The many
-repsonsibilities of this method include: output buffering, caching, cookies,
-errors, response headers, and the generation and evaluation of PHP code.</p>
-
-<p>To compile a template from a string in Smarty, you must prefix your template
-source code with the magic incantation <code>string:</code> and pass it as the name of the
-template to this &quot;fetch&quot; method. If the fifth parameter - <code>$display</code> - is true,
-then &quot;fetch&quot; also takes charge of cache invalidation and the sending of rendered
-template output as part of the response body. In short, this is very untidy code
-with an equally messy API.</p>
-
-<h2>Dependency Injection Done Right</h2>
-
-<p>Twig&#39;s flexibility and cleanliness here is a big win for the <a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency
-injection pattern</a>. It&#39;s a great example of how DI isn&#39;t just about maximising
-testability, and of why I think DHH is a little too extreme in <a href="http://david.heinemeierhansson.com/2012/dependency-injection-is-not-a-virtue.html">his criticism of
-it</a>. Twig is a clear example where DI has made the API better, not worse.</p>
-<div class="highlight"><pre><code class="text">$loader = new Twig_Loader_String;
-$twig = new Twig_Environment($loader);
-echo $twig-&gt;render(&#39;Hello !&#39;, array(&#39;name&#39; =&gt; &#39;Fabien&#39;));
-</code></pre></div>
-<p>As well as flexibility and code quality, this approach to loading templates
-happens to be very amenable to unit testing. Small classes with single
-responsibilities and few dependencies usually are easier to test than KLOC
-behemoths.</p>
-
-<p>That&#39;s it, really. Twig gets this right, and I think that&#39;s worth a little
-praise. Go Twig.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2013-07-22" pubdate="pubdate">
- JUL 22 2013
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
179 _site/blog/debian-squeeze-vagrant-base-box/index.html
@@ -1,179 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Debian Squeeze Vagrant Base Box</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Debian Squeeze Vagrant Base Box
- </h1>
- </header>
- <p>In an effort to suck less at dealing with all the various sysadmin-related tasks
-that come hand-in-hand with being a web developer, I&#39;m learning my way around
-<a href="http://vagrantup.com/">Vagrant</a> and <a href="http://www.opscode.com/chef/">Chef</a>. One of the many things I&#39;ve been struggling with is the
-lack of a Debian Squeeze vagrant box that actually works with my version of
-VirtualBox.</p>
-
-<p>I&#39;m not sure what the problem is here. One of the most common error messages
-complained that the guest additions in the base box were from a different
-version of VirtualBox from the one I&#39;m using. If that&#39;s an issue, perhaps it
-might be better if the likes of <a href="http://www.vagrantbox.es/">virtualbox.es</a> made the VirtualBox version of
-each box available.</p>
-
-<p>Thing is, it&#39;s Debian Squeeze or nothing as far as I&#39;m concerned, so the only
-option remaining was to build my own base box. The documentation for this is
-pretty great, but in the end I had to resort to a lot of Googling to figure
-various things out so this blog post attempts to unite all the information I
-needed in one place.</p>
-
-<h2>1. Install Debian in VirtualBox</h2>
-
-<p>I started by downloading <a href="http://www.debian.org/releases/squeeze/debian-installer/">debian-6.0.6-i386-netinst.iso</a> from the Debian
-homepage. Following Vagrant&#39;s <a href="http://vagrantup.com/v1/docs/base_boxes.html">base box guidelines</a>, I created a virtual machine
-with the following properties:</p>
-
-<ul>
-<li>40GB dynamically resizing drive</li>
-<li>360MB of memory allocation</li>
-<li>Audio disabled</li>
-<li>USB disabled</li>
-<li>NAT networking</li>
-</ul>
-
-<p>As per the recommendations, I chose a hostname of <code>vagrant-debian-squeeze</code> and
-a domain of <code>vagrantup.com</code>.</p>
-
-<h2>2. Install Required Software</h2>
-
-<p>Vagrant requires Ruby, RubyGems, Puppet, Chef and an SSH server to be present
-on the machine in order for it to work as a base box. To install these, I did
-this:</p>
-<div class="highlight"><pre><code class="bash">wget -O- http://opscode.com/chef/install.sh | bash
-</code></pre></div>
-<p>This is easier and more reliable than going through all the steps manually.</p>
-
-<h2>3. Remove Unwanted Software</h2>
-
-<p>Debian helpfully detects that you&#39;re installing it in VirtualBox and installs a
-bunch of related packages for you. We don&#39;t want them though, and they have to
-be removed in order to install the proper guest additions.</p>
-<div class="highlight"><pre><code class="bash">apt-get remove --purge virtualbox-ose-guest-x11
-apt-get autoremove
-apt-get remove --purge virtualbox-ose-guest-utils
-</code></pre></div>
-<p>This one was a pain to figure out. Much thanks to <a href="http://revcode.wordpress.com/2012/02/25/uninstalling-the-default-virtualbox-ose-guest-additions-on-debian/">a blog post on
-revcode.wordpress.com</a> for the life-saving Google search result.</p>
-
-<h2>4. Install Guest Additions</h2>
-
-<p>There&#39;s a button in VirtualBox that effectively inserts the guest additions as
-an imaginary CD-ROM. After pressing that, the commands to actually install them
-were as follows:</p>
-<div class="highlight"><pre><code class="bash">apt-get install module-assistant
-mount /media/cdrom
-sh /media/cdrom/VBoxLinuxAdditions.run
-</code></pre></div>
-<p>After this it politely suggested a reboot, so I did.</p>
-
-<h2>5. Break All Security</h2>
-
-<p>This next bit felt so wrong. The standard Vagrant base box has a pretty funky
-security model in order to make it convenient as a testing environment. The
-guidelines stipulate passwordless sudo privileges, which entails installing
-sudo and then immediately breaking off the locks.</p>
-<div class="highlight"><pre><code class="bash">apt-get install sudo sudo
-visudo
-</code></pre></div>
-<p>The line I added to <code>/etc/sudoers</code> was <code>%admin ALL=NOPASSWD: ALL</code>, or in
-English, &quot;Everyone in the group called &#39;admin&#39; can do anything they want to
-this box&quot;. After that, I ran <code>/etc/init.d/sudo restart</code> to make it so.</p>
-
-<h2>6. Hand over the keys</h2>
-
-<p>The standard vagrant username is &#39;vagrant&#39;, with password &#39;vagrant&#39;. I set this
-user account up during Debian installation, but there was more to it than that.
-The user must be added to the <code>admin</code> group.</p>
-<div class="highlight"><pre><code class="bash">groupadd admin
-usermod -G admin vagrant
-</code></pre></div>
-<p>For good measure, I also decided to disable root login with <code>passwd -l root</code>.</p>
-
-<h2>7. Enable SSH access</h2>
-
-<p>In order to be able to access the vm with <code>vagrant ssh</code>, the guidelines
-recommend using their standard <a href="http://github.com/mitchellh/vagrant/tree/master/keys/">insecure SSH key pair</a> which
-vagrant will use by default when connecting.</p>
-<div class="highlight"><pre><code class="bash">sudo apt-get install openssh-server
-wget https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub
-mkdir /home/vagrant/.ssh
-chmod 644 vagrant.pub
-mv vagrant.pub /home/vagrant/.ssh/authorized_keys
-</code></pre></div>
-<p>The line <code>AuthorizedKeysFile %h/.ssh/authorized_keys</code> was added to
-<code>/etc/ssh/sshd_config</code> to allow passwordless SSH access to take effect after a
-quick <code>/etc/init.d/ssh restart</code>.</p>
-
-<h2>8. Export box</h2>
-
-<p>With everything configured correctly, the next step was to turn off the VM and
-export it.</p>
-<div class="highlight"><pre><code class="bash">vagrant package --base debiansqueeze squeeze32.box
-</code></pre></div>
-<p>The name <code>debiansqueeze</code> there is what I named the VM itself in VirtualBox.</p>
-
-<h2>That&#39;s It</h2>
-
-<p>After that the box was ready to roll. Just gotta add it to Vagrant.</p>
-<div class="highlight"><pre><code class="bash">vagrant box add squeeze32 ~/squeeze32.box
-</code></pre></div>
-<p>From here on out it&#39;s plain old Vagrant usage. Hopefully all this effort will
-pay off in the long run when I can sit back and push systems changes to
-production with a beer in my hand.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2012-10-16" pubdate="pubdate">
- OCT 16 2012
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
BIN  _site/blog/decoupling-nested-backbone-views/lines.png
Deleted file not rendered
View
BIN  _site/blog/decoupling-nested-backbone-views/list.gif
Deleted file not rendered
View
BIN  _site/blog/decoupling-nested-backbone-views/map.gif
Deleted file not rendered
View
173 _site/blog/dont-use-requirejs-as-a-service-locator/index.html
@@ -1,173 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Don't Use RequireJS As A Service Locator</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Don't Use RequireJS As A Service Locator
- </h1>
- </header>
- <p>My latest project is a multiplayer implementation of chess in Javascript. I&#39;ve
-been using the project to modernise my Javascript skills a bit, so it&#39;s been
-strict TDD with <a href="http://requirejs.org/">RequireJS</a>, <a href="http://backbonejs.org/">Backbone</a>, and <a href="http://visionmedia.github.io/mocha/">Mocha</a>. Along the way, I&#39;ve
-encountered an interesting decision regarding whether or not to use my RequireJS
-AMD <code>define([])</code> statements as a service locator in addition to their
-<a href="http://requirejs.org/docs/whyamd.html#purposes">primary purpose</a> of referring to other units of code. I found myself tempted to
-do this, and when I looked into it online, it seemed I wasn&#39;t alone.</p>
-
-<p>The most common purpose for which I&#39;ve seen this approach employed is to
-facilitate the passing around of an event aggregator instance.</p>
-<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;Backbone&quot;</span><span class="p">,</span> <span class="s2">&quot;eventAggregator&quot;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">Backbone</span><span class="p">,</span> <span class="nx">vent</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
- <span class="nx">events</span><span class="o">:</span> <span class="p">{</span>
- <span class="s2">&quot;click&quot;</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
- <span class="nx">vent</span><span class="p">.</span><span class="nx">trigger</span><span class="p">(</span><span class="s2">&quot;element:click&quot;</span><span class="p">);</span>
- <span class="p">}</span>
- <span class="p">}</span>
- <span class="p">});</span>
-<span class="p">});</span>
-</code></pre></div>
-<p>I&#39;ve also seen this approach referred to as &quot;<a href="http://www.bennadel.com/blog/2319-Managed-Dependencies-vs-Dependency-Injection-In-RequireJS.htm">managed dependencies</a>&quot;, or even
-(incorrectly) as dependency injection, but it&#39;s just a variant of the service
-locator pattern. I&#39;m pretty sure that it&#39;s a bad idea.</p>
-
-<h2>It Combines The Service Locator Pattern With The Singleton Pattern</h2>
-
-<p>Service locators are characterised by dependent code invoking some sort of
-&quot;fetch me these dependencies&quot; API on some central registry. The dependent code
-uniquely identifies the required dependencies to the registry, and expects a
-specific instance of that dependency to be returned.</p>
-
-<p>Using RequireJS to load dependency instances directly is an example of the
-service locator pattern because it entails requesting the desired implementation
-of the dependency from RequireJS via the <code>define([])</code> array. Instead of simply
-depending on the interface of an injected dependency, this is a much more
-precise dependence on a specific implementation.</p>
-
-<p>Singletons are instantly recognisable for their Highlander-esque enforcement of
-the limit of one instance across the entire system. The singleton pattern
-mandates the explicit prevention of instantiation of any more than one instance
-of a class.</p>
-
-<p>Loading a dependency such as an event aggregator instance using RequireJS
-forces us to return an instance of our class in that dependency&#39;s <code>define</code>
-callback instead of just the class definition. This effectively turns our class
-into a singleton, as we preclude the loading of the class definition itself in
-favour of loading the same instance across the entire system.</p>
-<div class="highlight"><pre><code class="javascript"><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;underscore&quot;</span><span class="p">,</span> <span class="s2">&quot;backbone&quot;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">({},</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Events</span><span class="p">);</span>
-<span class="p">});</span>
-</code></pre></div>
-<h2>Tight Coupling Is Problematic</h2>
-
-<p>The problem with components that couple themselves tightly to other components
-is that they become difficult to isolate from the rest of the system. This
-impairs their <a href="/blog/code-i-like-twig-loaders/">composability</a>, and gradually
-leads towards a system in which the correctness of any given line of code is
-heavily dependent on many other disparate lines of code throughout the rest of
-the system.</p>
-
-<p>Continuing with the event aggregation example, the tight coupling of a view
-class to a specific event aggregator instance makes it awkward to execute just
-the code in the view class. Chances are, interaction with the view&#39;s public API
-will inadvertantly trigger listeners that have been registered on its event
-aggregator by other parts of the system. It ought to be trivial to isolate that
-view from the rest of the system, but the tight coupling introduced by the
-service locator pattern complicates matters.</p>
-
-<h2>Global State Is Problematic</h2>
-
-<p>The RequireJS project has a page in its documentation entitled &quot;<a href="http://requirejs.org/docs/whyamd.html">Why AMD?</a>&quot;.
-This page makes numerous references to the elimination of global variables as a
-benefit of the AMD approach to module loading. Global variables, and global
-state in general, are a notorious source of problems for developers of complex
-systems. Yet usage of RequireJS as a service locator puts singleton instances of
-dependencies into a global, system-wide scope, turning them into effective
-global variables.</p>
-
-<p>A dependency instance exposed globally to the whole system via RequireJS is
-opened up for tampering by any piece of code in any file. With the whole system
-sharing a single instance of a dependency, care must be taken to avoid putting
-that instance into a state that will cause problems later when other dependent
-code interacts with it. In the worst case scenario, this forces us to be mindful
-of the entire rest of our codebase whenever we modify code that interacts with
-these singletons.</p>
-
-<h2>It&#39;s Not About Testability</h2>
-
-<p>This is emphatically <em>not</em> a simple matter of preserving testability. The likes
-of <a href="http://sinonjs.org/">Sinon</a> and <a href="https://github.com/iammerrick/Squire.js/">Squire</a> negate many of the testing woes that this sort of
-practice would inflict in less dynamic languages than Javascript, such as Java
-or even PHP.</p>
-
-<p>The notion that dependency injection is all about testability is a <a href="http://en.wikipedia.org/wiki/Straw_man">straw man
-argument</a>. Testability is certainly a <em>benefit</em> of dependency injection in some
-languages, but the real core point of dependency injection is the principle of
-<a href="http://en.wikipedia.org/wiki/Inversion_of_control">inversion of control</a>. Writing code that has its dependencies injected, instead
-of independently seeking them out for itself, is about wanting code that we can
-control <em>externally</em> and easily isolate from the rest of the system.</p>
-
-<h2>It&#39;s About Software Quality</h2>
-
-<p>Javascript is rapidly maturing as a programming language, and it&#39;s being used to
-build ever larger and more complex systems. As this process happens, the
-Javascript community is gradually &quot;discovering&quot; and adopting software
-engineering principles that are considered baseline expectations in other
-languages because of the value they bring when dealing with large systems.
-JSLint is an example of this process in action. The emergence of TDD is another.</p>
-
-<p>I think it&#39;s irrational to treat any programming language as somehow &quot;exempt&quot;
-from established software engineering principles on a flimsy basis such as &quot;It&#39;s
-not Java&quot;, or &quot;<a href="http://david.heinemeierhansson.com/2012/dependency-injection-is-not-a-virtue.html">I&#39;m a Ruby programmer</a>&quot;, or even &quot;<a href="http://www.wordsbyf.at/2011/10/31/i-dont-write-javascript/">I don&#39;t write &#39;JavaScript&#39;</a>&quot;.
-Reality always sets in eventually. To me, avoiding misuse of RequireJS as a
-service locator seems a likely candidate for something that might become a
-widely acknowledged best practice in time.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2013-12-20" pubdate="pubdate">
- DEC 20 2013
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
2,579 _site/blog/feed.xml
0 additions, 2,579 deletions not shown
View
153 _site/blog/frontend-finite-state-machines/index.html
@@ -1,153 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Front-end Finite State Machines</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Front-end Finite State Machines
- </h1>
- </header>
- <p>For a while now I&#39;ve been working pretty hard on a new web application. It&#39;s
-probably the most complicated thing I&#39;ve built in terms of client-side code.
-The server-side stuff is as dumb as a wall compared to the sort of stuff I&#39;m
-used to, so it&#39;s generally been a refreshing change of pace. It uses
-<a href="http://backbonejs.org/">Backbone.js</a> to manage some of that front-end complexity, but even then I&#39;ve
-found it surprisingly difficult to avoid creating a tangled mess. Lack of
-practice, I guess.</p>
-
-<h2>The Problem</h2>
-
-<p>The nature of the particular feature that&#39;s been causing so much trouble is a
-<code>&lt;table&gt;</code> in which every row represents a database record and can be edited or
-deleted. This means every row needs a set of &quot;output&quot; elements, a set of
-<code>&lt;input&gt;</code> fields, and a delete button. This leads to a fairly large set of
-total possible states and state transitions. For example, opening the editor
-for one row means any other open editors must close. And while waiting for the
-server to save changes, the form&#39;s edit button must be replaced with some sort
-of activity indicator such as an <a href="http://ajaxload.info/">animated GIF</a>.</p>
-
-<p>It may sound simple, and most of the people reading this have probably built
-something similar at some point. What I&#39;ve been struggling with is achieving a
-100% confidence level that no combination of user actions can fuck up the
-veritable Javascript event juggling performance going on behind the scenes.</p>
-
-<p>Take the examples I gave earlier: what if the user clicks &quot;Save&quot; and then
-clicks &quot;Edit&quot; on another transaction <em>while the first one is still saving</em>?
-What happens to that save activity indicator GIF? A naively-written callback
-might simply hide the form without checking if it&#39;s actually ready to hide. The
-GIF is gone and the user thinks their changes are safely persisted on the
-server. Your user might even close the tab before finding out if their changes
-were actually stored, especially if you&#39;re being rammed by a big traffic spike
-which is hurting your response times.</p>
-
-<p>The breaking point for me came when I started enumerating all these kinds of
-things. Attempting to wrap up every state transition in a conditional that
-checks for every explicitly conflicting state was boring and difficult. The
-resulting code felt really fragile too.</p>
-
-<h2>The Solution</h2>
-
-<p>I decided to try using an
-<a href="http://en.wikipedia.org/wiki/Finite-state_machine">FSM</a> when I started
-noticing myself using the words &quot;state&quot; and &quot;state transitions&quot; a lot in some
-of the comments I was writing. I also vaguely remembered reading a blog post a
-long while ago advocating more usage of <a href="http://www.shopify.com/technology/3383012-why-developers-should-be-force-fed-state-machines">state machines in web
-development</a>.
-Half-remembered blog posts and vague hunches are apparently how I roll these
-days.</p>
-
-<p>My FiniteStateMachine class has these methods:</p>
-<div class="highlight"><pre><code class="text">constructor(states)
- Accepts an array of valid state names
-
-getState
- Returns the current state
-
-setState(state)
- Changes to a new state
- Throws a big sweaty hissy fit if it&#39;s not a known state
-
-on(eventName, callback)
- Binds a callback function to the given event
-</code></pre></div>
-<p>The very first thing I did with this was to remove all the <code>.hide()</code> and
-<code>.show()</code> calls from everything. In their place, I bound a function like this
-to the FSM&#39;s <code>change</code> event in each view:</p>
-<div class="highlight"><pre><code class="javascript"><span class="kd">function</span><span class="p">(</span><span class="nx">oldState</span><span class="p">,</span> <span class="nx">newState</span><span class="p">)</span> <span class="p">{</span>
- <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">removeClass</span><span class="p">(</span><span class="nx">oldState</span><span class="p">);</span> <span class="c1">// out with the old</span>
- <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">addClass</span><span class="p">(</span><span class="nx">newState</span><span class="p">);</span> <span class="c1">// in with the new</span>
-<span class="p">}</span>
-</code></pre></div>
-<p>Then I used CSS to dictate which elements should be visible in each state. Hide
-the save button while in the &quot;saving&quot; state and so on. This is nothing too
-clever and there are probably a million blog posts already advocating this
-approach.</p>
-
-<p>What&#39;s really nice about it, though, is best illustrated by my example from
-earlier. I now have an easy way to bind a callback that closes the form once
-saving is complete and it&#39;s returned to a <code>ready</code> state: </p>
-<div class="highlight"><pre><code class="javascript"><span class="nx">form</span><span class="p">.</span><span class="nx">fsm</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;state:ready&#39;</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="nx">form</span><span class="p">.</span><span class="nx">hide</span><span class="p">,</span> <span class="nx">form</span><span class="p">));</span>
-</code></pre></div>
-<p>This binds the view&#39;s current visual style to its behaviour in a way that I
-think is kind of neat. The visual style (the CSS class) changes at the exact
-same moment as the behaviour (Javascript callback) kicks in, and both are
-triggered by the same code in the FSM.</p>
-
-<h2>Meh</h2>
-
-<p>This isn&#39;t really anything that clever by proper Javascript developer
-standards. It may even lead to more difficulty in the long run, I don&#39;t know.
-It looks like a pretty successful little experiment right now though. The only
-thing of note about it really is that finite state machines have always seemed
-like quite a dusty old academic concept to me until now. Today though they&#39;ve
-really helped me get some code back under control. I guess the moral is: Pay
-more attention in Computer Science lectures, past-me, you lazy bastard.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2012-09-10" pubdate="pubdate">
- SEP 10 2012
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
107 _site/blog/i-should-never-build-a-time-machine/index.html
@@ -1,107 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>I Should Never Build A Time Machine</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- I Should Never Build A Time Machine
- </h1>
- </header>
- <p>Time and I aren&#39;t best friends. A while ago I learned the hard way why <code>60 * 60
-* 24</code> is often some of the worst code you could possibly write, and will
-forever be a little nervous around any code containing that calculation. It&#39;s a
-calculation that will work fine for 363 days of the year, just long enough for
-you to let your guard down before corrupting all your data and disappearing into
-the night until next time. That&#39;s another story though.</p>
-
-<p>I&#39;ve been doing some work recently generating some reports that involved
-restricting and grouping result sets by date. The date field is stored in a
-<code>DATETIME</code> column and I needed to turn that into a week number. I spent the
-longest time scratching my head wondering why all the numbers I was getting
-were off by the tinest bit. It turned out to be a MySQL quirk that I hadn&#39;t
-come across before.</p>
-
-<p>Every week has a number identifying its position in the year from 1 to 52. For
-example, it&#39;s currently week 20 of the year 2012, and on Monday May 21st it&#39;ll
-be week 21. In case you don&#39;t believe me:</p>
-<div class="highlight"><pre><code class="mysql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="nf">week</span><span class="p">(</span><span class="nf">now</span><span class="p">());</span>
-<span class="o">+-------------+</span>
-<span class="o">|</span> <span class="nf">week</span><span class="p">(</span><span class="nf">now</span><span class="p">())</span> <span class="o">|</span>
-<span class="o">+-------------+</span>
-<span class="o">|</span> <span class="mi">20</span> <span class="o">|</span>
-<span class="o">+-------------+</span>
-</code></pre></div>
-<p>Where it gets confusing is in that last second at midnight this Sunday. I was
-using the intuitively-named <code>WEEK()</code> function to determine the week number,
-which thinks that midnight on the 20th is part of week 21:</p>
-<div class="highlight"><pre><code class="mysql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="nf">week</span><span class="p">(</span><span class="s1">&#39;2012-05-20 00:00:00&#39;</span><span class="p">);</span>
-<span class="o">+-----------------------------+</span>
-<span class="o">|</span> <span class="nf">week</span><span class="p">(</span><span class="s1">&#39;2012-05-20 00:00:00&#39;</span><span class="p">)</span> <span class="o">|</span>
-<span class="o">+-----------------------------+</span>
-<span class="o">|</span> <span class="mi">21</span> <span class="o">|</span>
-<span class="o">+-----------------------------+</span>
-</code></pre></div>
-<p>This was throwing all my calculations off because I was making the assumption
-that any date on &#39;2012-05-20&#39; would be in week 20. It turns out that
-there was nothing wrong with that assumption, but <code>WEEK()</code> was the wrong
-function. The right tool for the job was <code>WEEKOFYEAR()</code>:</p>
-<div class="highlight"><pre><code class="mysql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="nf">weekofyear</span><span class="p">(</span><span class="s1">&#39;2012-05-20 00:00:00&#39;</span><span class="p">);</span>
-<span class="o">+-----------------------------------+</span>
-<span class="o">|</span> <span class="nf">weekofyear</span><span class="p">(</span><span class="s1">&#39;2012-05-20 00:00:00&#39;</span><span class="p">)</span> <span class="o">|</span>
-<span class="o">+-----------------------------------+</span>
-<span class="o">|</span> <span class="mi">20</span> <span class="o">|</span>
-<span class="o">+-----------------------------------+</span>
-</code></pre></div>
-<p>As it turns out, MySQL supports <a href="http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week">seven different ways</a> of
-deciding to what week number a given date corresponds. It&#39;s almost certainly all
-necessary functionality, but as usual, time proves treacherous to the unwary
-developer (me).</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2012-05-23" pubdate="pubdate">
- MAY 23 2012
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
310 _site/blog/index.html
@@ -1,310 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Blog</title>
- </head>
- <body>
-
-
-
-
-<article>
- <header>
- <h1>
- Blog
- </h1>
- </header>
-
-<article class="post row">
- <h2>
- <a href="/blog/dont-use-requirejs-as-a-service-locator/">
- Don't Use RequireJS As A Service Locator
- </a>
- </h2>
- <time datetime="2013-12-20" pubdate="pubdate">
- DEC 20 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/ternary-abuse/">
- Ternary Abuse
- </a>
- </h2>
- <time datetime="2013-12-09" pubdate="pubdate">
- DEC 09 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/xkcd-1288-and-tdd/">
- XKCD #1288 and TDD
- </a>
- </h2>
- <time datetime="2013-11-10" pubdate="pubdate">
- NOV 10 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/scrutinizer-ci-code-climate-for-php/">
- Scrutinizer CI: Code Climate For PHP
- </a>
- </h2>
- <time datetime="2013-10-09" pubdate="pubdate">
- OCT 09 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/active-record-as-a-database-cli/">
- Active Record As A Database CLI
- </a>
- </h2>
- <time datetime="2013-09-21" pubdate="pubdate">
- SEP 21 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/code-i-like-twig-loaders/">
- Code I Like: Twig Loaders
- </a>
- </h2>
- <time datetime="2013-07-22" pubdate="pubdate">
- JUL 22 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/all-your-code-should-help/">
- All Your Code Should "Help"
- </a>
- </h2>
- <time datetime="2013-05-19" pubdate="pubdate">
- MAY 19 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/monkey-patches-broke-my-build/">
- Monkey Patches Broke My Build
- </a>
- </h2>
- <time datetime="2013-04-28" pubdate="pubdate">
- APR 28 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/whitespace-sins/">
- Whitespace Sins
- </a>
- </h2>
- <time datetime="2013-03-26" pubdate="pubdate">
- MAR 26 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/tescos-self-checkout-traffic-lights/">
- Tesco's self-checkout traffic lights
- </a>
- </h2>
- <time datetime="2013-01-20" pubdate="pubdate">
- JAN 20 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/ppls-design/">
- ppl's design
- </a>
- </h2>
- <time datetime="2013-01-04" pubdate="pubdate">
- JAN 04 2013
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/yes-you-need-timestamps/">
- Yes, You Need Timestamps
- </a>
- </h2>
- <time datetime="2012-11-06" pubdate="pubdate">
- NOV 06 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/debian-squeeze-vagrant-base-box/">
- Debian Squeeze Vagrant Base Box
- </a>
- </h2>
- <time datetime="2012-10-16" pubdate="pubdate">
- OCT 16 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/more-on-finite-state-machines/">
- More On Finite State Machines
- </a>
- </h2>
- <time datetime="2012-09-11" pubdate="pubdate">
- SEP 11 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/frontend-finite-state-machines/">
- Front-end Finite State Machines
- </a>
- </h2>
- <time datetime="2012-09-10" pubdate="pubdate">
- SEP 10 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/null/">
- Null
- </a>
- </h2>
- <time datetime="2012-07-07" pubdate="pubdate">
- JUL 07 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/i-should-never-build-a-time-machine/">
- I Should Never Build A Time Machine
- </a>
- </h2>
- <time datetime="2012-05-23" pubdate="pubdate">
- MAY 23 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/the-mythical-one-off-script/">
- The Mythical One-Off Script
- </a>
- </h2>
- <time datetime="2012-04-21" pubdate="pubdate">
- APR 21 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/switch-true/">
- switch (true)
- </a>
- </h2>
- <time datetime="2012-03-17" pubdate="pubdate">
- MAR 17 2012
- </time>
-</article>
-
-
-
-<article class="post row">
- <h2>
- <a href="/blog/rollercoaster-code/">
- Rollercoaster Code
- </a>
- </h2>
- <time datetime="2012-03-05" pubdate="pubdate">
- MAR 05 2012
- </time>
-</article>
-
-
-
-<nav class="footer">
- <a href="/">henrysmith.org</a>
-</nav>
-
-
-
-
-</article>
- </body>
-</html>
-
View
123 _site/blog/monkey-patches-broke-my-build/index.html
@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Monkey Patches Broke My Build</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Monkey Patches Broke My Build
- </h1>
- </header>
- <p>The prevalence of monkey patching as a Ruby development practice is a complete
-pain in the arse. Sure, some of Ruby&#39;s expressiveness as a tool for building
-DSLs is derived from the ability to monkey patch things like <code>10.days.ago</code> into
-the core classes. Admittedly, I occasionally indulge my sweet tooth at the Rails
-all-you-can-eat syntactic sugar buffet. But it&#39;s not my favourite approach to
-software development by a long shot.</p>
-
-<p>A couple of months ago I wrote a little about the general awkwardness resulting
-from monkey patching. I&#39;ve been burnt worse since then, and now I have a
-concrete example which I think supports my point of view quite strongly.</p>
-
-<h2>Coveralls/Colorized/Colored Clusterfuck</h2>
-
-<p>Today I wanted to add a service called <a href="http://coveralls.io">Coveralls</a> to ppl&#39;s build process.
-Coveralls measures test coverage, provides statistics about test coverage over
-time, and supplies a dynamic README badge for advertising your project&#39;s
-commitment to thorough testing. It&#39;s a perfect fit for a project like ppl, so I
-was keen to get it running.</p>
-
-<p>Take a quick look at the <a href="https://github.com/h2s/ppl/commit/c64eba2ef563c33c2e862ec0cfdf1c008bd01eb3">commit which added Coveralls to ppl</a>. It&#39;s a tiny commit, and seemingly harmless. To my great
-surprise, <a href="https://travis-ci.org/h2s/ppl/jobs/6699000">it broke the build</a> on Travis CI. And which test did it break?</p>
-<div class="highlight"><pre><code class="text">Failures:
-
-1) Ppl::Format::Table#to_s should colorize columns if requested
- Failure/Error: @table.to_s.should eq &quot;\e[31m12345 \e[0m\e[33mJohn Doe \e[0m\e[34mjdoe@example.org \e[0m&quot;
-
- expected: &quot;\e[31m12345 \e[0m\e[33mJohn Doe \e[0m\e[34mjdoe@example.org \e[0m&quot;
- got: &quot;\e[0;31;49m12345 \e[0m\e[0;33;49mJohn Doe \e[0m\e[0;34;49mjdoe@example.org \e[0m&quot;
-
- (compared using ==)
-# ./spec/ppl/format/table_spec.rb:80:in `block (3 levels) in &lt;top (required)&gt;&#39;
-</code></pre></div>
-<p>The design of that test is actually a bit of a minor mistake on my part. The
-color adapter probably ought to be mocked out, as this test isn&#39;t really about
-the ANSI color escape codes themselves.</p>
-
-<p>On the plus side, this has exposed something very interesting: the escape codes
-surrounding the strings have changed subtly. And why is that? Because the
-Coveralls gem <a href="https://github.com/lemurheavy/coveralls-ruby/blob/2081d0382b7bd8796634d39d1c06f65241dac836/coveralls-ruby.gemspec#L19">depends on</a> a string colorization library called <a href="https://github.com/fazibear/colorize">colorize</a>. When
-Coveralls is loaded by the line <code>require &quot;coveralls&quot;</code>, colorize&#39;s String class
-monkey patches overwrite the ones previously made by
-<code>Ppl::Adapter::Color::Colored</code> when it loads the colored gem.</p>
-
-<h2>What. The. Fuck.</h2>
-
-<p>Did you catch that? My project&#39;s test suite failed because one of Coveralls&#39;
-dependencies changed the behaviour of Ruby&#39;s core <code>String</code> class in a way that
-overwrites changes previously made to that class by a dependency of ppl. This is
-absolute insanity. It&#39;s not even anybody&#39;s <em>fault</em>, but rather an inevitable
-consequence of monkey patching.</p>
-
-<p>I&#39;m quite new to Ruby, so I have to rely on others for perspective on this
-approach to Ruby development. Judging by Avdi Grimm&#39;s 2008 post,
-&quot;<a href="http://devblog.avdi.org/2008/02/23/why-monkeypatching-is-destroying-ruby/">Monkeypatching is Destroying
-Ruby</a>&quot;,
-it was considered quite hip five years ago. Here we are in 2013, and installing
-a code coverage tool has literally <em>changed the output of my code</em>. It&#39;s pretty
-clear that Avdi was right, anyway.</p>
-
-<p>Refinements look set to right some of these wrongs, but Ruby 2.0 is still warm
-from the oven, and projects like ppl will probably be supporting 1.9 for a long
-time to come. In the meantime, I&#39;ve decided to start treating monkey patches
-more or less like a code smell. Not because they are necessarily fragile in
-themselves, but because of the fragility they so inscrutably create in other
-code.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2013-04-28" pubdate="pubdate">
- APR 28 2013
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
154 _site/blog/more-on-finite-state-machines/index.html
@@ -1,154 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>More On Finite State Machines</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- More On Finite State Machines
- </h1>
- </header>
- <p>In my last post I wrote about how I&#39;d created a simple finite state machine in
-order to help manage some of the complex state transitions going on in some
-Javascript I&#39;ve been working on. At this point I&#39;m 100% convinced that in some
-circumstances this really is the best approach available.</p>
-
-<h2>What Happened</h2>
-
-<p>It very quickly became clear that I am far too lazy to build and maintain a
-Javascript FSM implementation. As with everything else in life, I immediately
-turned to Google for answers. This led to the <a href="https://github.com/jakesgordon/javascript-state-machine">Javascript state machine
-library</a>, by a guy called <a href="http://codeincomplete.com">Jake Gordon</a>. Here&#39;s a <a href="http://codeincomplete.com/posts/2011/8/19/javascript_state_machine_v2/example/">nifty demo</a> of the library in
-action, and here&#39;s some example code from the README:</p>
-<div class="highlight"><pre><code class="javascript"><span class="kd">var</span> <span class="nx">fsm</span> <span class="o">=</span> <span class="nx">StateMachine</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
- <span class="nx">initial</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span>
- <span class="nx">events</span><span class="o">:</span> <span class="p">[</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;warn&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;yellow&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;panic&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;yellow&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;red&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;calm&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;yellow&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;clear&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;yellow&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;green&#39;</span> <span class="p">}</span>
-<span class="p">]});</span>
-</code></pre></div>
-<p>This is a very nice little library, and I decided to try to apply it to my
-project in the hope of abandoning my own <code>statemachine.js</code> file.</p>
-
-<h2>Holy Shit</h2>
-
-<p>The payoff from integrating this library has been amazing. I&#39;ve achieved an
-unexpectedly <em>huge</em> reduction in the amount of code in my Backbone views by
-using it. I&#39;m actually going to go ahead and just paste in a big clump of
-example code at this stage to illustrate the extent to which I have been
-liberated from babysitting the DOM.</p>
-<div class="highlight"><pre><code class="javascript"><span class="nx">Example</span><span class="p">.</span><span class="nx">Views</span><span class="p">.</span><span class="nx">Row</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
-
- <span class="c1">// this bit is just plain old Backbone stuff</span>
- <span class="nx">events</span><span class="o">:</span> <span class="p">{</span>
- <span class="s1">&#39;click .delete-open&#39;</span> <span class="o">:</span> <span class="s1">&#39;deleteClicked&#39;</span><span class="p">,</span>
- <span class="s1">&#39;click .delete-cancel&#39;</span> <span class="o">:</span> <span class="s1">&#39;deleteCancelled&#39;</span><span class="p">,</span>
- <span class="s1">&#39;click .delete-confirm&#39;</span> <span class="o">:</span> <span class="s1">&#39;deleteConfirmed&#39;</span><span class="p">,</span>
- <span class="s1">&#39;click .editor-open&#39;</span> <span class="o">:</span> <span class="s1">&#39;editClicked&#39;</span><span class="p">,</span>
- <span class="s1">&#39;click .editor-cancel&#39;</span> <span class="o">:</span> <span class="s1">&#39;editCancelled&#39;</span><span class="p">,</span>
- <span class="s1">&#39;click .editor-save&#39;</span> <span class="o">:</span> <span class="s1">&#39;saveClicked&#39;</span>
- <span class="p">},</span>
-
- <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
- <span class="c1">// a tiny little bit of FSM boilerplate</span>
- <span class="k">this</span><span class="p">.</span><span class="nx">onchangestate</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">stateChange</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span>
- <span class="k">this</span><span class="p">.</span><span class="nx">startup</span><span class="p">();</span>
- <span class="p">},</span>
-
- <span class="nx">stateChange</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">eventName</span><span class="p">,</span> <span class="nx">oldState</span><span class="p">,</span> <span class="nx">newState</span><span class="p">,</span> <span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
- <span class="k">if</span> <span class="p">(</span><span class="nx">event</span> <span class="k">instanceof</span> <span class="nx">jQuery</span><span class="p">.</span><span class="nx">Event</span><span class="p">)</span> <span class="p">{</span>
- <span class="c1">// my twitter bootstrap dropdown options</span>
- <span class="c1">// have href=&quot;#&quot; so this stops that from</span>
- <span class="c1">// moving the viewport to the top of the page</span>
- <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
- <span class="p">}</span>
- <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;state_&#39;</span> <span class="o">+</span> <span class="nx">oldState</span><span class="p">);</span>
- <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">).</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;state_&#39;</span> <span class="o">+</span> <span class="nx">newState</span><span class="p">);</span>
- <span class="p">}</span>
-
-<span class="p">});</span>
-
-<span class="nx">StateMachine</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
- <span class="nx">target</span><span class="o">:</span> <span class="nx">Example</span><span class="p">.</span><span class="nx">Views</span><span class="p">.</span><span class="nx">Row</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span>
- <span class="nx">events</span><span class="o">:</span> <span class="p">[</span>
- <span class="c1">// this is my favourite part: StateMachine</span>
- <span class="c1">// turns the names here into methods in the</span>
- <span class="c1">// view, so the Backbone events fire these</span>
- <span class="c1">// state transitions automatically!</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;startup&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;none&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;editClicked&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;editor_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;editCancelled&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;editor_ready&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;saveClicked&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;editor_ready&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;save_activity&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;saveSuccess&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;save_activity&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;saveFailure&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;save_activity&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;editor_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;deleteClicked&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;delete_confirm&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;deleteCancelled&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;delete_confirm&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;viewer_ready&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;deleteConfirmed&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;delete_confirm&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;delete_activity&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;deleteSuccess&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;delete_activity&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;hidden&#39;</span> <span class="p">},</span>
- <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;deleteFailure&#39;</span><span class="p">,</span> <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;delete_activity&#39;</span><span class="p">,</span> <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;delete_confirm&#39;</span> <span class="p">}</span>
- <span class="p">]</span>
-<span class="p">});</span>
-</code></pre></div>
-<p>This deceptively concise code perfectly manages all the states and state
-transitions. I haven&#39;t cut anything out for brevity. The above code provides a
-rock-solid state machine that keeps the following set of possible UI states in
-check and makes it almost <em>impossible</em> for a confusing or unexpected change in
-appearance to occur and upset users.</p>
-
-<p><img src="/blog/more-on-finite-state-machines/states.png" alt="Alt text"></p>
-
-<h2>Good Times</h2>
-
-<p>At one point I was seriously contemplating having three views for each of these
-rows because the state transition bullshit was becoming unmanageable. I&#39;ve
-never been more glad that I stopped to think instead of just hacking away.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2012-09-11" pubdate="pubdate">
- SEP 11 2012
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
BIN  _site/blog/more-on-finite-state-machines/states.png
Deleted file not rendered
View
131 _site/blog/null/index.html
@@ -1,131 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-
-</script>
-
-
-
- <title>Null</title>
- </head>
- <body>
-
-
-
-
-<article class="post">
- <header>
- <h1>
- Null
- </h1>
- </header>
- <p>Here&#39;s a bit of MySQL behaviour that I didn&#39;t expect. I spent a good half an
-hour scratching my head about this one until it finally clicked. The problem
-was this: I wanted to filter out rows where a certain column matched a certain
-value, which is the simplest WHERE clause imaginable. Strangely, when this
-clause was present in the query, other rows were filtered out too. Turns out
-MySQL thinks about <code>null</code> in a different way to most other things I&#39;ve worked
-with so far.</p>
-
-<p>Here&#39;s what PHP does when ask to compare something to <code>null</code>:</p>
-<div class="highlight"><pre><code class="text">php &gt; var_dump(&quot;String&quot; === null);
-bool(false)
-</code></pre></div>
-<p>And Javascript:</p>
-<div class="highlight"><pre><code class="text">$ node
-&gt; &quot;String&quot; === null;
-false
-</code></pre></div>
-<p>Comparing a string to <code>null</code> returns false. It&#39;s intuitive: a string value is
-not the same as a <code>null</code> value. MySQL doesn&#39;t see it this way, check it out:</p>
-<div class="highlight"><pre><code class="text">mysql&gt; SELECT &quot;String&quot; = NULL;
-+-----------------+
-| &quot;String&quot; = NULL |
-+-----------------+
-| NULL |
-+-----------------+
-</code></pre></div>
-<p>MySQL&#39;s point of view on <code>null</code> is <a href="http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html">a little more philosophical</a>. The
-rationale seems to be that the question of whether a known value is equal to an
-unknown value can only be answered with the unknown value itself. This can have
-unexpected effects, at least from the point of view of programmers like me who
-are used to an answer of &quot;No&quot; to that question. Take this database table, for
-example:</p>
-<div class="highlight"><pre><code class="text">mysql&gt; SELECT * FROM example;
-+----+---------+
-| id | name |
-+----+---------+
-| 1 | 1st Row |
-| 2 | NULL |
-| 3 | 3rd Row |
-+----+---------+
-</code></pre></div>
-<p>Imagine you have the string &quot;3rd Row&quot; in some variable, and you want to get
-the set of all rows whose name doesn&#39;t match that value. You&#39;re thinking
-<code>WHERE name != &#39;3rd Row&#39;</code>, right?</p>
-<div class="highlight"><pre><code class="text">mysql&gt; SELECT *
- -&gt; FROM example
- -&gt; WHERE name != &#39;3rd Row&#39;;
-+----+---------+
-| id | name |
-+----+---------+
-| 1 | 1st Row |
-+----+---------+
-</code></pre></div>
-<p>The second row is missing. MySQL compares &#39;3rd Row&#39; to <code>null</code>, getting a <code>null</code>
-in return, which means the row doesn&#39;t make the cut. If you know you have <code>null</code>
-values in there and don&#39;t necessarily want to filter them out, then as far as I
-can tell you actually do have to add an extra <code>WHERE</code> clause:</p>
-<div class="highlight"><pre><code class="text">mysql&gt; SELECT *
- -&gt; FROM example
- -&gt; WHERE name != &#39;3rd Row&#39;
- -&gt; OR name IS NULL;
-+----+---------+
-| id | name |
-+----+---------+
-| 1 | 1st Row |
-| 2 | NULL |
-+----+---------+
-</code></pre></div>
-<p>This seems like a design decision intended specifically to trip up people like
-me and make us sit up and pay attention so that we actually consider whether we
-want to filter out these values or not. As such it&#39;s probably a really good
-thing for protecting data from careless developers. Certainly surprised me
-though.</p>
-
- <footer>
- <span class="vcard">
- <address class="author">
- <em class="fn">
- <a class="url" href="/">
- Henry Smith
- </a>
- </em>
- </address>
- <time datetime="2012-07-07" pubdate="pubdate">
- JUL 07 2012
- </time>
- </span>
- </footer>
-</article>
- </body>
-</html>
-
-
View
220 _site/blog/ppls-design/index.html
@@ -1,220 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="alternate" type="application/rss+xml" href="/blog/feed.xml" />
- <link rel="stylesheet" type="text/css" href="/stylesheets/henrysmith/8.css" />
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
-
-
-<script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-18857416-1']);
- _gaq.push(['_trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- })();
-