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

  <title></title>
  <link href="http://mcdowall.info/atom.xml" rel="self"/>
  <link href="http://mcdowall.info/"/>
  <updated>2011-10-29T14:56:56-04:00</updated>
  <id>http://mcdowall.info/</id>
  <author>
    <name>John McDowall</name>
    
  </author>

  
  <entry>
    <title>My Notes From the Movie Startup.com</title>
    <link href="http://mcdowall.info/2011/10/my-notes-from-the-movie-startup-com"/>
    <updated>2011-10-29T14:50:00-04:00</updated>
    <id>http://mcdowall.info/2011/10/my-notes-from-the-movie-startup-com</id>
    <content type="html">&lt;p&gt;This weekend I watched Startup.com, and here's some notes I jotted down while watching it.&lt;/p&gt;

&lt;!--more--&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We should all trust that any one of us will represent a vision of the business that will be seconded and thirded by anyone in the team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We should never be in a confrontation / debate stage in front of anybody.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There's a sadness about watching ideas grow until they're beyond the point where you can do anything for them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As soon as someone says &quot;There's no need for this to be ugly&quot; it's going to get ugly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Meet your competitors, befriend them. Force them into making plays earlier than they want to. But only if your product tangibly is better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't make your company about your personality as a CEO who 'doesn't lose'.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It doesn't matter if the market is big, it's a question of who can make money in it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always have a third party who can arbitrate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a 'Days to Live' countdown board with focussed tasks to achieve in that time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everyone should use the product, CEO down to the person who answers the phones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be critical on the status of your product's functionality. If it doesn't work, say it doesn't work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep momentum on Testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security of your product, your office, everything is paramount.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be concerned about revenue. Don't be concerned about the Board. It's their prerogative to fire you or re*shuffle as they see fit, and they will do so.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goals need to be specific and actionable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any company with two CEOs is in trouble.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even in 2001, mobile phones had some horrific extendable antennas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sales cycles are always longer than anticipated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Things change. That's the best part.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decline happens quickly and noticeably.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The scariest part of this movie is Kaleil Tuzman driving along a wet highway, chanting to a CD and reading from a book held against the wheel.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Announcing: The Beast Master</title>
    <link href="http://mcdowall.info/2011/10/announcing-the-beast-master"/>
    <updated>2011-10-28T18:32:00-04:00</updated>
    <id>http://mcdowall.info/2011/10/announcing-the-beast-master</id>
    <content type="html">&lt;p&gt;&lt;img class='right ' src='/images/figures/thebeastmaster_thumb.png' alt=' The Beast Master ' title=' The Beast Master '&gt;
I needed a specific tool that would help record when a piece of software was deployed to a particular environment, keeping track of the who, the when and the SHA1 from Github that was deployed. So I wrote The Beast Master in a day.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;It's written in Ruby 1.9.2 and Sinatra, and currently has an RSpec test suite coverage of 94%. It provides a simple HTTP API with two endpoints, one providing a dashboard showing the latest releases, the other a POST endpoint to mark a release with. There's the ability to enable Basic HTTP authentication on both endpoints.&lt;/p&gt;

&lt;p&gt;All in all, it took about a day to drive out the functionality TDD style, following a strict Red-Green-Refactor approach.&lt;/p&gt;

&lt;p&gt;It's located up on &lt;a href=&quot;http://github.com/johnmcdowall/the-beast-master&quot;&gt;http://github.com/johnmcdowall/the-beast-master&lt;/a&gt; and I welcome you to try it out, send feedback or make improvements.&lt;/p&gt;

&lt;p&gt;Bon appetit.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Announcing delimitedfileformats.info (I Need Help)</title>
    <link href="http://mcdowall.info/2011/09/announcing-delimitedfileformats-info-i-need-help"/>
    <updated>2011-09-24T13:00:00-04:00</updated>
    <id>http://mcdowall.info/2011/09/announcing-delimitedfileformats-info-i-need-help</id>
    <content type="html">&lt;p&gt;&lt;img class='right ' src='/images/figures/delimited.png' alt=' Delimited File Formats ' title=' Delimited File Formats '&gt;
I've come to understand the horror that is working with Text based delimited file formats, such as CSV, TSV or what have you. There are some published specs for both file formats that can be used as guidance when it comes to implementing write support for these formats, but mostly every file I see is broken in some way that expects the parser to be omniscient about the original context of the file.&lt;/p&gt;

&lt;p&gt;So, in an effort to increase awareness around Delimited file formats, I've started a project on &lt;a href=&quot;https://github.com/johnmcdowall/Delimited-File-Formats&quot;&gt;github&lt;/a&gt;, and a published site at &lt;a href=&quot;http://delimitedfileformats.info&quot;&gt;http://delimitedfileformats.info&lt;/a&gt; that will attempt to give people useful information about how to read and write these particular file formats in a way that is consistent and productive.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But I need help.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I need help with the design, the content, and feedback on the overall usefulness of the site.&lt;/p&gt;

&lt;p&gt;I've made an initial stab at it, but I'm hoping for some lovely team work on this...&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Software and Old Houses</title>
    <link href="http://mcdowall.info/2011/09/software-and-old-houses"/>
    <updated>2011-09-24T11:43:00-04:00</updated>
    <id>http://mcdowall.info/2011/09/software-and-old-houses</id>
    <content type="html">&lt;p&gt;&lt;img class='right ' src='/images/figures/old_house.jpg' alt=' This old House ' title=' This old House '&gt;
Old Houses are products of accretion. Over the course of many years they gather new extensions, tweaked facades, upgraded central or under-floor heating systems, alarm systems, downstairs washrooms and nursereys. And usually, once one project is completled, you'll bask in the glow of it for a while until it's forgotten about and the next one embarked upon. Just like Software Design.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;The house I live in is big and old: over 80 years. It's been split up so that a couple live in the back portion, my wife and I live in the front half, and there's a basement apartment. Sound travels in funny ways in old houses.&lt;/p&gt;

&lt;p&gt;You see, there are remnants of what were once ducts for the purposes of a forced air central heating system, all through the house. The air vents are now sealed, but the ornamentation on the baseboard that gives away their purpose is still there. The ducts lie embedded within the walls still. Long forgotten about, these heating ducts were probably installed at great expense at the time, for what was felt to be the ultimate in home comfort: hot air blown into the rooms from a central heater!&lt;/p&gt;

&lt;p&gt;At some point, the old air heater was pulled out, radiators were found and installed, and a fancy Swedish boiler system now silently and efficiently pumps hot water around the piping and heats the house. And the ducts remain, in the walls. Now sealed up and silent. Except for when they carry sound in funny ways. Old houses are like that.&lt;/p&gt;

&lt;p&gt;Occasionally, we are treated to the sounds of someone somewhere else in the house enjoying vigorous, short lived coitus, the echoes of it carried inside the bones of the house, inside these long forgoten about ducts that serve no purpose. Should the ducts be ripped out? That would be very costly, and damaging to the house. Ripping them out would deliver no real value to anyone. So they stay. Silently embedded within the walls.&lt;/p&gt;

&lt;p&gt;Those ducts are much like the infastructure portions of almost every software design that's ever been written. Look at your own current project’s codebase. Is there something in there, some remnant of infrastructure that was built with the greatest of hopes and expectations, only to be sidestepped when the problem was more fully understood?&lt;/p&gt;

&lt;p&gt;Removing that code might be too hard now, because nobody writes perfect software. Some brittle tests somewhere might flare up, or a method call somewhere might explode, in a certain circumstance. Deadlines are looming and everything's on fire. Maybe you work in a job where your boss says things like 'You don't get paid to remove code, you get paid to write it!'.&lt;/p&gt;

&lt;p&gt;So that code sits there, inside your digital walls.&lt;/p&gt;

&lt;p&gt;Software Design is like building houses. The construction continues long after the thing is 'finished', and you end up living with the choices you make for a long time, usually forever. Sometimes it's ok to paper over some minor cracks and live your life.&lt;/p&gt;

&lt;p&gt;And sometimes, in the night, you hear odd noises carried by those old ducts.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Continuum Movie</title>
    <link href="http://mcdowall.info/2011/08/continuum-movie"/>
    <updated>2011-08-27T12:14:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/continuum-movie</id>
    <content type="html">&lt;p&gt;While stumbling about the &lt;a href=&quot;http://flavors.me/&quot;&gt;flavors.me&lt;/a&gt; site, I found a landing page for a new Indie movie called &lt;strong&gt;CONTINUUM&lt;/strong&gt;. The premise is probably more interesting from a technical standpoint than plot wise:&lt;/p&gt;

&lt;!--more--&gt;




&lt;blockquote&gt;&lt;p&gt;Synopsis:&lt;br/&gt;Osmond speeds down an open highway in retreat of his mysterious past. When he stops the car and steps off the path, he finds himself locked in a fractal time loop, and is doomed to realize his fate over and over... and over.&lt;/p&gt;&lt;p&gt;Production:&lt;br/&gt;I'm making a movie about a time loop, which usually entails the main character meeting or interacting with their self in some way. That's the whole point. I wanted to achieve this for my film, but as one continuous shot, and without the use of hidden cuts, visual effects, or twin actors. After countless hours of brainstorming and lots of advice from really smart people, we found a practical way to pull it off. I'm not going to give away the secrets, so you'll have to wait and see for yourselves!&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;I'm intrigued to see how this could be done without the use of any of the usual staples of time travel movies, using only practical means.&lt;/p&gt;

&lt;p&gt;You can check out the Movie's micro-site &lt;a href=&quot;http://www.continuum-film.com/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Excellent Newsletter Signup Example</title>
    <link href="http://mcdowall.info/2011/08/excellent-newsletter-signup-example"/>
    <updated>2011-08-18T22:21:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/excellent-newsletter-signup-example</id>
    <content type="html">&lt;p&gt;Getting people to sign up for your newsletter can be a tricky task, and everyone's trying to get their customers to do the same. I found an excellent example of how to make it clear what people are signing up for.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;&lt;img class='' src='/images/figures/bvckup-signup.png' alt=' Bvckup Newsletter Signup ' title=' Bvckup Newsletter Signup '&gt;&lt;/p&gt;

&lt;p&gt;This image is from the &lt;a href=&quot;http://bvckup.tumblr.com/post/9101329123/please-confirm-your-email-address&quot;&gt;Bvckup blog&lt;/a&gt;. The header is clear and succinct: &lt;i&gt;'To receive News and Promotions'&lt;/i&gt;. The email box has clear text that instructs the user how to complete the signup, with an arrow on the right hand side giving the affordance that this action will complete something significant.&lt;/p&gt;

&lt;p&gt;And then the piste de résistance: &lt;i&gt;'Low volume, one-click unsubscribe'&lt;/i&gt;. This statement alone is genius. It's the very equivalent of a social proof substitute in that it tells the user that this newsletter won't deluge them with emails and if they want to unsubscribe, then they only have one click to make. Skilfully, both of the primary objections a user could have for signing up to this newsletter are tackled.&lt;/p&gt;

&lt;p&gt;Bravo.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Intent</title>
    <link href="http://mcdowall.info/2011/08/intent"/>
    <updated>2011-08-12T17:21:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/intent</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;The Mayor: Intent? How did you establish that? &lt;br/&gt;Harry Callahan: When a naked man is chasing a woman through an alley with a butcher's knife and a hard-on, I figure he isn't out collecting for the Red Cross! &lt;br/&gt;[walks out of the room] &lt;br/&gt;The Mayor: He's got a point.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;A quote from the excellent Clint Eastwood movie &lt;strong&gt;Dirty Harry&lt;/strong&gt;. How do we establish someone's intent? By observing their actions, and the context of those actions. True intent is often disguised in a veil of language and ego-based posturing, but actions in their proper context aways reveal the nature of someone's intent.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Wallpaper: Freedom</title>
    <link href="http://mcdowall.info/2011/08/wallpaper-freedom"/>
    <updated>2011-08-09T22:58:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/wallpaper-freedom</id>
    <content type="html">&lt;p&gt;Sometimes I get the feelin' in my bones to make a wallpaper. So here's one. It's licensed with &lt;a href=&quot;http://creativecommons.org/licenses/by-nc/3.0/&quot;&gt;Attribution-NonCommercial&lt;/a&gt;, so you can do whatever you want with it as long as you attribute me, and don't use it for commercial purposes. Have a blast.&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='/images/figures/Freedom_Thumb.jpg' alt=' Freedom ' title=' Freedom '&gt;
&lt;img class='' src='http://i.creativecommons.org/l/by-nd/3.0/88x31.png' alt=' License ' title=' License '&gt;&lt;/p&gt;

&lt;p&gt;Click through for the download link.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Download it &lt;a href=&quot;/images/figures/Freedom.zip&quot;&gt;here&lt;/a&gt;. Drop me a line at john at mcdowall dot info if you love it, or hate it.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Data Is</title>
    <link href="http://mcdowall.info/2011/08/data-is"/>
    <updated>2011-08-03T19:18:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/data-is</id>
    <content type="html">&lt;p&gt;A great image about what Data is, sent to me from my friend &lt;a href=&quot;http://twitter.com/Daniellaanne&quot;&gt;@Daniellaanne&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='/images/figures/Data-and-cake.jpg' alt=' Data and Cake ' title=' Data and Cake '&gt;&lt;/p&gt;

&lt;p&gt;From the &lt;a href=&quot;http://flowingdata.com/2011/07/28/open-thread-data-as-cake-and-frosting/&quot;&gt;Flowing Data&lt;/a&gt; blog.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Long Term Goal One</title>
    <link href="http://mcdowall.info/2011/08/long-term-goal-one"/>
    <updated>2011-08-01T20:37:00-04:00</updated>
    <id>http://mcdowall.info/2011/08/long-term-goal-one</id>
    <content type="html">&lt;blockquote&gt;&lt;p&gt;‘I am striving not to become the grand old man of the profession, but to close my design doors when I reach forty-five’&lt;/p&gt;&lt;footer&gt;&lt;strong&gt;Louis Swart&lt;/strong&gt;&lt;cite&gt;&lt;a href='http://www.graphicdesignmuseum.nl/lab/blog/?p=474'&gt;Louis Swart in an Interview on His Thirtieth Birthday&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;

</content>
  </entry>
  
  <entry>
    <title>Ruby Is Slow? She's Fast Enough for You</title>
    <link href="http://mcdowall.info/2011/07/ruby-is-slow-shes-fast-enough-for-you"/>
    <updated>2011-07-31T12:37:00-04:00</updated>
    <id>http://mcdowall.info/2011/07/ruby-is-slow-shes-fast-enough-for-you</id>
    <content type="html">&lt;p&gt;For the past while, Twitter have been moving gradually from their legacy Ruby on Rails codebase to Java and the JVM. This has been greeted with the usual cries of '&lt;em&gt;Rails is slow!&lt;/em&gt;', '&lt;em&gt;Ruby is slow!&lt;/em&gt;' and hand-wringing in the startup circles that accompanies such announcements. At OSCON 2011, Raffi Kirkorian gave a presentation rounding up the reasons why Twitter has moved to the JVM.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;349&quot; src=&quot;http://www.youtube.com/embed/ohHdZXnsNi8&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Sadly, Raffi is sloppy with his usage of the terminology. When he speaks of 'Ruby' he actually means the MRI 1.8.x runtime.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h2&gt;Looking Deeper&lt;/h2&gt;

&lt;p&gt;It's a well understood issue in the Ruby community that MRI 1.8.x doesn't have a very good threading model. In fact, it's pathetic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRI 1.8.x&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Green_threads&quot;&gt;Green Threads&lt;/a&gt; are used, which is a scheme where the underlying Virtual Machine schedules the threads instead of the Operating System's Kernel. As such, they are managed in User Space with all of the accompanying drawbacks that doing so entails, particularly in multi-core environments. It is worth noting, however, that Green Thread were the only option in Java 1.1. In Ruby, this means that all of these 'fake' threads map to one single actual process thread.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MRI 1.9.x&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Native threading was introduced, but the runtime still has a Global Interpreter Lock (GIL) that prevents a lot of concurrency. It seems that each revision of MRI 1.9.x makes this lock more granular, which improves the concurrency situation. The decision for this seems to be in order to make an easy path for C extension developers to migrate to truly concurrent threads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JRuby 1.5.x and later&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Native threading is provided through the JVM and there is no Global Interpreter Lock. Ruby threads are Java threads. You would have exactly the same level of concurrency here as you would writing Java apps on the JVM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rubinius&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Since Rubinius aims to have 1.8.x / 1.9.x level compatibility, it also has a GIL, although there is a branch called Hydra which aims to reduce or remove the GIL as much as possible.&lt;/p&gt;

&lt;h2&gt;THE MYSTERY IS REVEALED&lt;/h2&gt;

&lt;p&gt;Raffi points to the fact that when &lt;a href=&quot;http://blog.twitter.com/2008/07/finding-perfect-match.html&quot;&gt;Twitter acquired Summize&lt;/a&gt; in 2008, they inherited an infrastructure entirely written in Java.&lt;/p&gt;

&lt;p&gt;Moreover, the engineering blog recently announced they &lt;a href=&quot;http://engineering.twitter.com/2011/04/twitter-search-is-now-3x-faster_1656.html&quot;&gt;made Search three times faster&lt;/a&gt; by moving to a Java server called Blender.&lt;/p&gt;

&lt;p&gt;Additionally, Twitter have also spent a lot of time and money &lt;a href=&quot;http://engineering.twitter.com/2011/03/building-faster-ruby-garbage-collector.html&quot;&gt;improving the MRI 1.8.7 garbage collector&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;WHAT'S REALLY HAPPENING&lt;/h2&gt;

&lt;p&gt;Twitter say that JRuby's ecosystem was immature, and a lot of the clients they would need were &lt;a href=&quot;http://www.infoq.com/articles/twitter-java-use&quot;&gt;simply too slow&lt;/a&gt;. That article in particular has a headline claiming 'Twitter Shifting More Code to JVM, Citing Performance and Encapsulation As Primary Drivers'. Claiming moving to any language because it gives you better encapsulation is just bullshit, especially when Rails developers do have a tendency to write monolithic applications: this is nothing to do with Rails and everything to do with the developers who come to Rails.&lt;/p&gt;

&lt;p&gt;Then there's &lt;a href=&quot;http://www.linkedin.com/in/rkrikorian&quot;&gt;Raffi&lt;/a&gt; himself, a former co-founder of WattzOn which was written using &lt;a href=&quot;http://www.slideshare.net/raffikrikorian/scala-wattzon-sitting-in-a-tree&quot;&gt;Scala&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In short, Twitter can't see past MRI 1.8.7, inherited a lot of Java code (and undoubtedly a bunch of Java developers along with it), and instead of exploring JRuby to exploit native threads made the decision to consolidate on a Java based technology stack. Blender became three times faster not because it was moved to Java, but because Twitter finally took advantage of native threads via the JVM.&lt;/p&gt;

&lt;h2&gt;CONCLUSION&lt;/h2&gt;

&lt;p&gt;Twitter do have a tough time scaling largely because they locked themselves into MRI 1.8.7. Java isn't giving them anything they didn't already have as a language, in fact quite the opposite is true. The JVM is providing features to them that they arguably could have leveraged using JRuby.&lt;/p&gt;

&lt;p&gt;It seems that Twitter's move to the JVM and Java is motivated because of the acquisition of some Java codebases and engineering talent, and a lack of genuine understanding of what Ruby and Rails has to offer in these modern days we live in.&lt;/p&gt;

&lt;p&gt;Twitter have a history of making really poor engineering decisions. Like &lt;a href=&quot;http://engineering.twitter.com/2010/06/perfect-stormof-whales.html&quot;&gt;not monitoring their internal network&lt;/a&gt;, not placing indices on tables and choosing obvious passwords for their admin systems. Could the move to Java and the JVM be based purely on not understanding what was built and how to manage it, and a desire to move to more familiar grounds for the new engineers?&lt;/p&gt;

&lt;p&gt;That said, Twitter is also an unique case in terms of scale and real time performance requirements. The reality is that you will never be in the position of having to deal with as much traffic and real time requirements as Twitter is when you are starting up or trying to prove an idea. Chances are you'll get very far being able to iterate more quickly on Rails and still handle scaling up all you need to. Most shops aren't building real time trading platforms. Shopify, for example, are serving millions of requests are &lt;a href=&quot;http://news.ycombinator.com/item?id=2825916&quot;&gt;100% Ruby on Rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So cease the hand-wringing. You can make bad engineering decisions in any language. Go build something awesome, fast.&lt;/p&gt;

&lt;h2&gt;FOOTNOTE&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;I don't mention C# and ASP.NET. In this case you'll be so bogged down in being caught up on the Microsoft treadmill and then swallowed alive by the costs of your Bizspark licenses when they come a-knockin' that you'll be overtaken by almost anybody else. You will have some fast-rendering webpages though. Nice.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Don't use TempFile in RSpec specs</title>
    <link href="http://mcdowall.info/2011/07/dont-use-tempfile-in-rspec-specs"/>
    <updated>2011-07-28T17:33:00-04:00</updated>
    <id>http://mcdowall.info/2011/07/dont-use-tempfile-in-rspec-specs</id>
    <content type="html">&lt;h2&gt;Problem&lt;/h2&gt;

&lt;p&gt;I had inherited some tests that used Ruby's &lt;a href=&quot;http://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/classes/Tempfile.html&quot;&gt;TempFile&lt;/a&gt; to create a temporary file which then had some data written to it, and the was path passed along to the rest of the test. This worked fairly well until suddenly one of the tests just started failing randomly, and as it turns out TempFile would fail to create the temporary file it was asked to and proceed without any kind of warning. Later on in the test the file didn't exist, so the test failed.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;So I created a simple little spec to test out TempFile on its own:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;test_tempfile_spec.rb &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rb'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;tempfile&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Testing Tempfile&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;should always create the temp file&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;testthetempfile&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;.tmp&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;SOME DATA&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tempfile&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Run the test, get a green dot. Hmm.&lt;/p&gt;

&lt;p&gt;However, running the test in concert with the rest of the test suite causes the error to reveal itself:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;pre&gt;&lt;code&gt;Failures:

  1) Testing Tempfile should always create the temp file
     Failure/Error: File.size?( tempfile ).should == 9
       expected: 9
            got: nil (using ==)&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;The temporary file hadn't been created.&lt;/p&gt;

&lt;p&gt;I finally isolated one spec in the suite that when run with all of the other specs, and the temp file spec, caused any Tempfile not to be created, and the above failure to appear. Testing that suspected spec with the tempfile spec only... did not cause the error to happen.&lt;/p&gt;

&lt;p&gt;So I'm left with an error on creating a Tempfile that only happens when the entire test suite is run, and only when a particular spec is included in the suite. Logging the Tempfile paths when they are created shows that the are all unique, so there don't seem to be any naming conflicts. The error happened under both 1.9.2-p180 and 1.9.2-p290.&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;Don't use Tempfile in RSpec specs. RSpec may or may not be the culprit here, but the code in the specs is simple and straightforward and trying to fully isolate the issue would take up more time than I have at the moment. Maybe it's an OSX issue. It could be a John issue. But out of all the file access code in the specs, only Tempfile is failing. Don't use it. It introduces weird system level dependancies into your tests. Don't use it. It makes your specs run slower. Don't use it.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>The Ten Principles of Good Data</title>
    <link href="http://mcdowall.info/2011/06/the-ten-principles-of-good-data"/>
    <updated>2011-06-29T19:36:00-04:00</updated>
    <id>http://mcdowall.info/2011/06/the-ten-principles-of-good-data</id>
    <content type="html">&lt;p&gt;Taking a cue from my old pal Dieter Rams, I've been thinking a
lot about the principles and properties of &quot;Good Data&quot;, which to me has
properties above what any old run of the mill data you might find lying in the
street has. The list is by no means definitive or even completely coherent,
but it represents a brain dump of my thoughts on the topic.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Update: Added 'accurate' from a comment on Hacker News, and an interesting
post on crawl-ability &lt;a href=&quot;http://datamining.typepad.com/data_mining/2011/07/is-data-open-if-it-cant-be-crawled.html&quot; title=&quot;Is Data Open if it can't be crawled?&quot;&gt;here&lt;/a&gt; which pushes us to 12 principles!&lt;/p&gt;

&lt;p&gt;Here is my list:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Good Data is accurate. It is factually correct.&lt;/li&gt;
&lt;li&gt;Good Data is contextual. All interpretation of Data requires a context within which the interpretation takes place.&lt;/li&gt;
&lt;li&gt;Good Data is useful. The Data bears some use in a context outside that of its own production.&lt;/li&gt;
&lt;li&gt;Good Data is temporally well defined. The Data captures some specific time period.&lt;/li&gt;
&lt;li&gt;Good Data is semantically correct. The Data doesn't need to be scrubbed or cleaned.&lt;/li&gt;
&lt;li&gt;Good Data is long lasting. The Data can always be retrieved.&lt;/li&gt;
&lt;li&gt;Good Data is maleable. The Data can be re-processed into new Data formats.&lt;/li&gt;
&lt;li&gt;Good Data is valuable. The Data carries some financial or social value to someone in the correct context.&lt;/li&gt;
&lt;li&gt;Good Data is accessible. The Data can be accessed on any device and any medium.&lt;/li&gt;
&lt;li&gt;Good Data is social. The Data can be shared, referenced and a community built around it.&lt;/li&gt;
&lt;li&gt;Good Data is irrefutable. The Data's provenance and history is verifiable.&lt;/li&gt;
&lt;li&gt;Good Data is crawl-able. The spiders of the web are able to find the data and consume it.&lt;/li&gt;
&lt;/ol&gt;

</content>
  </entry>
  
  <entry>
    <title>Why Rails 3.1 streaming means you still have to think about your head</title>
    <link href="http://mcdowall.info/2011/06/why-rails-3-1-streaming-means-you-still-have-to-think-about-your-head"/>
    <updated>2011-06-04T23:03:00-04:00</updated>
    <id>http://mcdowall.info/2011/06/why-rails-3-1-streaming-means-you-still-have-to-think-about-your-head</id>
    <content type="html">&lt;p&gt;Rails 3.1 will introduce &lt;a href=&quot;http://weblog.rubyonrails.org/2011/4/18/why-http-streaming&quot; title=&quot;Rails Blog&quot;&gt;Streaming Responses&lt;/a&gt;.
The blog entry is a bit disingenuous as it says &quot;In particular, if you flush
the head of an HTML document &lt;strong&gt;CSS and JavaScript files are going to be
fetched in parallel&lt;/strong&gt;, while the server works on generating content.&quot; The
implication here is that the CSS and JavaScript files themselves are going to
be fetched in parallel, and the blog post goes on to say that &quot;Modern clients
do not even block on JavaScript files as old ones did&quot;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Let's look at this in more detail.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;CSS and JavaScript files are going to be fetched in parallel&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Watch &lt;a href=&quot;http://railscasts.com/episodes/266-http-streaming&quot; title=&quot;RailsCasts - Streaming&quot;&gt;this RailsCast on the new upcoming Streaming&lt;/a&gt;, specifically at
2m58s. You'll see that when streaming is enabled, the HEAD is rendered back
form the server immediately, while the main BODY response is built up in
memory, server-side. What will the browser do here? It will start processing
those script tags serially, with a &lt;a href=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html&quot; title=&quot;HTTP/1.1 Pipelining&quot;&gt;maximum of two requests at a time&lt;/a&gt; per
hostname. Because of this, Steve Souders suggested that as many blocking
script tags as possible be put &lt;a href=&quot;http://developer.yahoo.com/performance/rules.html#js_bottom&quot; title=&quot;YSlow performance&quot;&gt;after the body&lt;/a&gt;, or &lt;a href=&quot;http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/&quot; title=&quot;Souders.&quot;&gt;other techniques
used&lt;/a&gt; to load the scripts asynchronously. Mozilla have a great, &lt;a href=&quot;http://www.mozilla.org/projects/netlib/http/pipelining-faq.html&quot; title=&quot;Pipelining FAQ&quot;&gt;still
relevant post about this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What happens if you don't do this? Your users will sit at a white, blank
page needlessly while those external blocking scripts are loaded and
processed. Even if your modern browser supports issuing more than two requests
per hostname, chances are there are Proxies or Gateways in between you and the
target server that support no more than two requests. &lt;strong&gt;So the main BODY
content could still arrive from Rails 3.1 before those exernal SCRIPT and
asset links have been fully loaded. &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This statement should have read 'CSS and JavaScript files are going to be
fetched in &lt;strong&gt;parallel to the main BODY&lt;/strong&gt;,&lt;strong&gt; and those files potentially loaded
faster by modern browsers and infrastructure&lt;/strong&gt;&quot;&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Modern clients do not even block on JavaScript files as old ones did&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;This may be true for the latest Webkit, but how important an issue this is for
you depends on what range of Browsers your application should support. I can't
find any conclusive reference material about this and it's beyond my current
patience to scour development forums and checkins for each browser out there.
I personally find the idea of just ramping up pipelined connections somewhat
worrying, after all the HTTP/1.1 spec is clear:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;These guidelines are intended to&lt;strong&gt; improve HTTP response times&lt;/strong&gt; and &lt;strong&gt;avoid
congestion&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This statement should have read '&lt;strong&gt;there are some modern clients that attempt
to further improve the SCRIPT loading and evaluation process&lt;/strong&gt;'.&lt;/p&gt;

&lt;p&gt;Incidentally, Streaming responses were part of ASP.NET 2.0, and the same
problems with too many SCRIPT and external asset tags existed then as now.
It's therefore not crazy to say that all web applications will benefit
from improvements in browser and internet infrastructure technology.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You still need to think carefully about how your SCRIPT tags will affect the end user experience. &lt;/strong&gt;There is no magic solution, and Rails 3.1 will not magically alleviate you of these concerns. Even if all modern browsers can look at a document and begin intelligently prefetching SCRIPT referenced assets, there is no guarantee about how quickly those assets will load, and the user should not be penalized with a white screen while your application stalls.&lt;/p&gt;

&lt;p&gt;Specifically with respect to Rails 3.1, streaming will bring it's ability to
stream content in line with many other web frameworks out there. It's long
overdue.&lt;/p&gt;

&lt;p&gt;Until you hear definitively otherwise, from &lt;a href=&quot;http://stevesouders.com/&quot; title=&quot;Steve Souders&quot;&gt;people who really know the fabric
of the Internet and HTTP&lt;/a&gt;, you'd be wise to keep to the roads and at the
very least A/B test the shit out of any new approach you try.&lt;/p&gt;

&lt;p&gt;If anyone has any clarifications they'd like to make to my understanding, I
welcome them!&lt;/p&gt;

&lt;p&gt;Updates (Comments on original article)&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;My guess is the Rails team is expecting that by baking in an easy way to do concatenation and minification, each page should really require only one css and one js file from inside the application anyhow, and these can safely be put in a streamed head response. Things loaded from Facebook or elsewhere outside of your control obviously should still be placed at the end of the body. But your points are a good reminder that this is not a simple issue.&lt;/p&gt;&lt;footer&gt;&lt;strong&gt;Adam&lt;/strong&gt;&lt;cite&gt;&lt;a href='http://www.electriceloquence.net/'&gt;www.electriceloquence.net/&amp;hellip;&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;




&lt;blockquote&gt;&lt;p&gt;The data about connections per host and whether loading SCRIPT tags blocks comes from this project http://www.browserscope.org/?category=network (it is linked at the bottom of the blog post).&lt;/p&gt;&lt;p&gt;The streaming response accounts one connection, so even in old browsers that only support two connections (eg IE7) depending on how heavy is content generation, they may still have time to fetch everything before the second chunk arrives. You’ve parallelized something for sure, one parallel connection at a time.&lt;/p&gt;&lt;p&gt;So yes, if you need to support old browsers this is not black and white. It depends on your particular application.&lt;/p&gt;&lt;p&gt;Note that streaming has no benefit for fast responses, in a similar way to not having any benefit for static files. Also little benefit if the client has the assets in cache. So you will typically enable it only for heavy and upfront views, and have normal responses for the rest of the website.&lt;/p&gt;&lt;p&gt;I think streaming will be exceptional rather than the norm, and it has also issues with compression we are working on. Point is you have the feature implemented if you need it.&lt;/p&gt;&lt;footer&gt;&lt;strong&gt;Xavier Noria&lt;/strong&gt;&lt;cite&gt;&lt;a href='http://hashref.com/'&gt;hashref.com/&amp;hellip;&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;

</content>
  </entry>
  
  <entry>
    <title>When You Buy Apple You Pay for Design</title>
    <link href="http://mcdowall.info/2011/05/when-you-buy-apple-you-pay-for-design"/>
    <updated>2011-05-26T13:00:00-04:00</updated>
    <id>http://mcdowall.info/2011/05/when-you-buy-apple-you-pay-for-design</id>
    <content type="html">&lt;p&gt;That’s right. Design with a capital D. If you don’t care about that or don’t understand Design then move along – I want you off my lawn.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;It’s perennially fashionable to complain about how much Apple products cost. The most visible attack point for Apple is their range of notebooks, which range from $999 for the current MacBook, up to $2,499 for the top of the range MacBook Pro. A lot of people feel that these are exorbitant prices for such machinery, and point to Dell or anyone else who makes ‘comparable’ units for less cost. “I can buy a Dell for $400 less and it will work just as well!” they cry. Well, yes, you can. And quite frankly, you, should.&lt;/p&gt;

&lt;p&gt;Aside: I’m not going to touch on ecological concerns or working practices, as quite frankly child slaves in China is a secret shame of many companies and a byproduct of our Capitalist way of life and if we were to incorporate that argument we would find ourselves saying we do not need any of this stuff and we should cease all exploitative production.&lt;/p&gt;

&lt;p&gt;Dieter Rams, former Head of Design at Braun A.G. – one of the most historically significant consumer product companies yet,  and during his time there he cooked up the following ten rules of Design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is innovative – Rams states that possibilities for innovation in design are unlikely to be exhausted since technological development is always offering new opportunities for innovative design. He also highlights that innovative design always develops in tandem with innovative technology and can never be an end in and of itself.&lt;/li&gt;
&lt;li&gt;Makes a product useful – A product is bought to be used. It has to satisfy certain criteria, not only functional, but also psychological and aesthetic. Good design emphasises the usefulness of a product whilst disregarding anything that could possibly detract from it.&lt;/li&gt;
&lt;li&gt;Is aesthetic – Only well-executed objects can be beautiful. The aesthetic quality of a product is integral to its usefulness because products used every day have an effect on people and their well-being.&lt;/li&gt;
&lt;li&gt;Makes a product understandable – It clarifies the product’s structure. Better still, it can make the product clearly express its function by making use of the user’s intuition. At best, it is self-explanatory.&lt;/li&gt;
&lt;li&gt;Is unobtrusive – Products and their design should be both neutral and restrained, to leave room for the user’s self-expression. Products fulfilling a purpose are like tools and are neither decorative objects nor works of art.&lt;/li&gt;
&lt;li&gt;Is honest – Honest design should not attempt to make a product seem more innovative, powerful or valuable than it really is. It should not attempt to manipulate the consumer with promises that cannot be kept.&lt;/li&gt;
&lt;li&gt;Is long-lasting – It should avoid being fashionable and therefore never appears antiquated. Unlike fashionable design, it lasts many years – even when the trend may be in favor for disposable products.&lt;/li&gt;
&lt;li&gt;Is thorough down to the last detail – Nothing must be arbitrary or left to chance in the design of a product since care and accuracy in the design process show respect towards the consumer.&lt;/li&gt;
&lt;li&gt;Is environmentally friendly – Good design should make an important contribution to the preservation of the environment by conserving resources and minimizing physical and visual pollution throughout the lifecycle of the product.&lt;/li&gt;
&lt;li&gt;Is as little design as possible – Dieter Rams makes the distinction between the common “Less is more” and his strongly advised “Less, but better” highlighting the fact that this approach focuses on the essential aspects thus, the products are not burdened with non-essentials. The desirable result would then be purer and simpler.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here is an example of Ram’s work:&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://upload.wikimedia.org/wikipedia/commons/a/a4/Braun_audio_310.jpeg' alt='' title=''&gt;&lt;/p&gt;

&lt;p&gt;Look at that thing. Look at it! When was it designed? This year? Maybe the latter half of the first decade of this century? No! 1971.&lt;/p&gt;

&lt;p&gt;Does it bear a resemblance to Apple products? If so, it’s due to Apple’s chief designer, Jonathon Ive, being heavily influenced by Ram’s principles, rather than Ram himself. To get a better understanding of this you can watch Gary Hustwit’s excellent Objectified documentary on Industrial Design.&lt;/p&gt;

&lt;p&gt;Look at this fan. Look at it!&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://gadgets.boingboing.net/gimages/ebaybraunfan.jpg' alt='' title=''&gt;&lt;/p&gt;

&lt;p&gt;Again, designed in the early 1970′s, this desk fan by Braun is an absolute joy and pleasure to look at on your desk, use, touch and listen to. It could be a desk fan for the office or the home, such that its aesthetics don’t constrain it to either domain as its design honest, understandable, speaks to its function, unobtrusive, innovative… I’ve been lucky enough to see one on Pete Forde’s desk and it follows from Ram’s principles of design perfectly. I would love to own one. But I could also own this:&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://di108.shoppingshadow.com/images/di/59/75/46/4d6775624753564a673572676e3145744a6151-149x149-0-0.jpg' alt='' title=''&gt;&lt;/p&gt;

&lt;p&gt;Sigh.&lt;/p&gt;

&lt;p&gt;At Apple, Jonathon Ive and his team works to unbelievable lengths to design every Apple product, making meticulous designs, iterating, refining and polishing. Apple hire chemical engineers to figure out ways to make the chemistry in the battery different and better, so that it lasts many hours longer than their competitors (this secret chemistry is the reason MacBook batteries became locked into the unit – second market companies would make inferior batteries that would damage the brand).&lt;/p&gt;

&lt;p&gt;Even the Headphones are meticulously designed at Apple:&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://storeimages.apple.com/1848/as-images.apple.com/is/image/AppleInc/MB770?wid=326&amp;hei=326&amp;fmt=jpeg&amp;qlt=95&amp;op_sharpen=0&amp;resMode=bicub&amp;op_usm=0.5,0.5,0,0&amp;iccEmbed=0&amp;layer=comp' alt='' title=''&gt;&lt;/p&gt;

&lt;p&gt;And yes, they cost $29, but if by now you don’t understand the labour and aesthetics that has been brought to you, I can’t help you. This is great design, made affordable to the masses, at the cheapest cost a Capitalist business is able to do so.&lt;/p&gt;

&lt;p&gt;Apple consistently produce products that change the world, and their design is key to that (see Ram’s principles above), and they do so at cost margins that absolutely no one else in the industry, not Dell, not RIM and their laughable Playbook, are able to even touch.&lt;/p&gt;

&lt;p&gt;Why do they do this? To skin us consumers for money?&lt;/p&gt;

&lt;p&gt;No. They do it because they care about the product and its design.&lt;/p&gt;

&lt;p&gt;And they believe that should be worth something.&lt;/p&gt;

&lt;p&gt;But if you don’t believe design has any value, enjoy reading this review of Dell’s latest morally bankrupt design void that does everything worse than the very thing they are aping.&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://www.blogcdn.com/www.engadget.com/media/2011/05/20110522-20054823--img8008.jpg' alt='' title=''&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Introducing the Deskbook</title>
    <link href="http://mcdowall.info/2011/04/introducing-the-deskbook"/>
    <updated>2011-04-25T12:52:00-04:00</updated>
    <id>http://mcdowall.info/2011/04/introducing-the-deskbook</id>
    <content type="html">&lt;p&gt;I have a fascination with looking at pictures of people’s desks. It’s weird.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;A while back, it was all the rage for people to post pictures on their Flickr accounts of their desks and show what they worked on: what type of computer, notebook, desk toys and what not. But not so much anymore.&lt;/p&gt;

&lt;p&gt;So I tweeted one night asking if there was such a site in existence where you could just go and browse pictures of people’s desks, partly out of curiosity and partly out of inspiration. John Lepp of Agents of Good replied with ‘desk book?’ and the rest, as they say, is history.&lt;/p&gt;

&lt;p&gt;I took the chance of a day off for the Easter weekend break to literally just throw something together and get it up as fast as humanly possible. I bought the domain name the night I had the conversation with John Lepp, and had been hosting a partial taunt to him at that domain as a single page site, so it was purely a matter of building something quick and deploying it to my server.&lt;/p&gt;

&lt;p&gt;I naturally chose Rails and S3 to build the site. HTML and CSS3 were literally thrown together without any concern for semantics or best practice. The first version was ready in six hours. There were and are no tests. So at 2am on Friday 22nd April I pushed the thing live and tweeted some folk I know and sent them the URL, packed my bags and got up at the crack of dawn the next day and headed to Barrie, where I’d been invited for dinner by my friend Kimberley MacKenzie of Ontario Nature.&lt;/p&gt;

&lt;p&gt;Checking the site briefly on the Saturday morning revealed that I’d forgotten about and oft neglected client – the Google Spider. Fixing this, I re-deployed and got on the Greyhound to Barrie.&lt;/p&gt;

&lt;p&gt;Later that night I checked my Twitter to see that Mr Lepp had busted the site open and it had a bunch of new uploads and was all still working! With one flaw – the Like functionality was busted. Oh well. Much beer was consumed in celebration.&lt;/p&gt;

&lt;p&gt;On the Sunday morning, I cracked open my laptop, made the fixes and pushed the changes, fixing the issue. Spending a lovely day up at Lake Huron, I packed my stuff and headed back to Toronto on the Greyhound.&lt;/p&gt;

&lt;p&gt;On the bus, I started thinking: automated tweets when new uploads are made, Disqus for comments, some Ads to maybe try to cover hosting costs, and a little bit of spit and polish. Cracking open the laptop I quickly started sketching out the changes courtesy of Greyhound WiFi, got home and finished up the rough edges and pushed the changes live. Done. All in I’d say I spent about 8-10hrs on the site.&lt;/p&gt;

&lt;p&gt;So check it out – &lt;a href=&quot;http://thedeskbook.com&quot;&gt;http://thedeskbook.com&lt;/a&gt; – and upload your desk!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Parsing the UK National Rail Enquiries Feed at the Command Line</title>
    <link href="http://mcdowall.info/2011/03/parsing-the-uk-national-rail-enquiries-feed-at-the-command-line"/>
    <updated>2011-03-15T12:56:00-04:00</updated>
    <id>http://mcdowall.info/2011/03/parsing-the-uk-national-rail-enquiries-feed-at-the-command-line</id>
    <content type="html">&lt;p&gt;The National Rails Enquiry site really annoys me. For some reason, even though I’m not logging in, the developers implemented a session time out across the whole site. I can understand why they might want to do that, but in this case it seems particularly unnecessary.&lt;/p&gt;

&lt;p&gt;So, after getting fed up having my initial search query bombed out by the session time out and having to go through the whole station selection process again, I spent some time figuring out how to consume their JSON data feed using CURL, AWK and the deadly SED.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;I used the Chrome developer tools to see what XHR calls were being made to populate the Live Departure board which comes across in the HTML as a table with an empty body (&lt;em&gt;SIGH&lt;/em&gt;). Then, after discovering the call, I basically treat the returned JSON as a giant string and throw away the useless parts; I could have used jsawk, but I didn’t want to introduce another dependency that might not be on all machines.&lt;/p&gt;

&lt;p&gt;If you run the following at mostly any UNIX / Linux command line:&lt;/p&gt;

&lt;div&gt;&lt;script src='https://gist.github.com/717990.js?file='&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;pre&gt;&lt;code&gt;echo &amp;quot;Trains from HYN to GLQ&amp;quot; &amp;amp;&amp;amp; curl --silent \
--user-agent &amp;quot;Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7&amp;quot; \
--referer &amp;quot;http://ojp.nationalrail.co.uk/en/s/ldbboard/dep/HYN/GLQ/To&amp;quot; \
&amp;quot;http://ojp.nationalrail.co.uk/en/s/ldb/liveTrainsJson?departing=true&amp;amp;liveTrainsFrom=Hyndland&amp;amp;liveTrainsTo=Glasgow+Queen+Street&amp;amp;serviceId=&amp;quot; \
| sed -e 's/[{&amp;quot;&amp;amp;;/&amp;quot;}]/''/g' | sed -e 's/ltbrgt/-''/g' | \
awk '{n=split($0,a,&amp;quot;,&amp;quot;); for (i=6; i&amp;lt;=n-2; i++) { printf(&amp;quot;%s %-25s %-20s\n&amp;quot;,a[i+0],a[i+1],a[i+2]); i+=5}}'
&lt;/code&gt;&lt;/pre&gt;&lt;/noscript&gt;&lt;/div&gt;


&lt;p&gt;You’ll get a nicely formatted display of a live departure board on the command line. A simple lookup of the station codes on the National Rail Enquiries website and a substitution of the values in the above script and you’ll have a custom version for your preferred route. You would need to make sure to update the Title, the referer URL string and the liveTainsJson call.&lt;/p&gt;

&lt;p&gt;As a passing note, it’s interesting to note that they went to the bother of having Airport style codes for all of the train stations, and then for the data feed just reverted back to doing a full station name lookup. Also, I’m by no means a bash guru, so if you can improve the script let me know!&lt;/p&gt;

&lt;p&gt;Now for extra geek points, if you’re on OSX, grab yourself GeekTool 3, and use the above as a Shell script to have the output permanently displayed on your desktop!&lt;/p&gt;

&lt;p&gt;Voila!&lt;/p&gt;

&lt;p&gt;&lt;img class='' src='http://media.tumblr.com/tumblr_lcjv0o9Nbi1qe0mu7.png' alt='' title=''&gt;&lt;/p&gt;
</content>
  </entry>
  
</feed>

