<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>The Life of a Radar</title>
 
 <link href="http://ryanbigg.com" />
 <updated>2012-02-03T08:09:40+11:00</updated>
 <id>http://ryanbigg.com/</id>
 <author>
   <name>Ryan Bigg</name>
   <email>radarlistener@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ryanbigg" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="ryanbigg" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Free Help</title>
   <link href="http://ryanbigg.com/2012/01/free-help" />
   <updated>2012-01-31T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2012/01/free-help</id>
   <content type="html"><![CDATA[<p>Sigh. Here I&#8217;m going to sound like one of <em>those</em> celebrities. But I thought I should lay down some ground rules, so here goes.</p>

<p>Yesterday, I received a 1,063 word email from a non-profit organisataion asking me for advice on whether or not they should use Rails or Django for their new project. They begin with:</p>

<blockquote>
<p>We found your answers and profile on Stack Overflow. We&#8217;re reaching out to you because we&#8217;d like your advice on a new nonprofit project, <span>name</span>, and the language/app framework we should use to develop it.</p>
</blockquote>

<blockquote>
<p>We have a fairly small budget to build the framework and to do betas of the first seven sites, so it&#8217;s crucial we pick the right framework. We are trying to choose between Django and Rails, and we want to make the right choice.</p>
</blockquote>

<p>Quite obviously, my answer is going to be heavily biased in one direction. I&#8217;m sure you can guess which one.</p>

<p>Before yesterday, I&#8217;d never even heard of this charity, nor spoken to the person who sent me the email. Basically, up until this point, we&#8217;ve done <em>nothing</em> for each other. Their questions obtusely relate to Rails, and definitely doesn&#8217;t relate to what I get paid to work on.</p>

<p>So I read the email anyway. It explains what the charity does and what they&#8217;d like their new platform to do. Then at the bottom, they ask if I could &#8220;take a look at the high-level requirements&#8221; and link me to a Google Docs Spreadsheet. Inside this spreadsheet, there&#8217;s 32 very wordy questions, like this one:</p>

<blockquote>
<p>We need the front ends and backends to run fast. Many of the backend pages will have fairly intensive reports drawing on lots of data from user pages, such as nonprofits being able to run reports of total donations over periods of time, recent donations, etc. We think speed is a top priority.</p>
</blockquote>

<p>Each question, by my estimates, would take one hundred to five hundred words to answer adequately. So at a minimum, around 3,200 words of mine to answer their questions. This is from a <em>complete stranger</em> in a private conversation between myself and them. Do you know what other situation this happens in usually?</p>

<p>Oh yeah, <strong>paid consulting</strong>. But there&#8217;s nothing in the email that indicates that I will get anything more than a warm and fuzzy feeling from answering it.</p>

<p>Like I said before, this is not related to anything that I do. This is <em>extra</em> work. It&#8217;s in a private conversation, so my answers won&#8217;t benefit anybody else. If this question pops up again, chances are that I will have to answer it again, and that&#8217;s not cool.</p>

<p>These kinds of emails are basically a three-times-a-week deal, and I&#8217;m over it. While I enjoy helping people <em>for free</em>, I will only do so in <a href='http://stackoverflow.com'>a public forum where other people can benefit from the answers</a>. If you want to contact me privately, then I will ask for some sort of reward for it, because <em>very</em> few people are going to benefit from it.</p>

<p>These kinds of questions have no regard for my time, and all I get from them is a feeling of being used for my talents. Kind of like a whore, just without the money changing hands thing.</p>

<p>No more.</p>]]></content>
 </entry>
 
 <entry>
   <title>Moving Out: Down to Melbourne</title>
   <link href="http://ryanbigg.com/2012/01/moving-out-down-to-melbourne" />
   <updated>2012-01-09T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2012/01/moving-out-down-to-melbourne</id>
   <content type="html"><![CDATA[<p>Oops, spoilers!</p>

<p>One year, four months ago I <a href='http://ryanbigg.com/2010/08/moving-out-for-reals'>moved out of a place in Camperdown in
Sydney</a> to a more remote suburb called Narwee. If you don&#8217;t know where that is (and judging by the conversations I&#8217;ve had with many of you, <em>nobody</em> does), it&#8217;s a South-Western suburb of Sydney, best described as &#8220;Go south to the airport, then about as far west&#8221;. You could Google Maps it if you like. I&#8217;ll wait.</p>

<p>It was there that I moved in with a guy called Tim and basically rented a room and shared the house for $200. It suited me fine, as I spent quite a lot of that time in there writing a book. The trainline nearby got me into and out of the city every single day that I needed it, bar one or two times where somebody decided to fight one of the trains.</p>

<p>When I came back from Adelaide recently, Tim arrived back also and told me that he has a friend who he would like to move in and so he asked me (very nicely, might I add) to move out by the end of January. Fair enough, it&#8217;s his place. This was on the 28th of December.</p>

<p>So then I needed to find a place. If I stay until February this year, then it&#8217;ll be two years in Sydney. During that time, I&#8217;ve always heard Melbourne compared to Sydney favourably. Things like &#8220;Melbourne&#8217;s like Sydney, but with more fun&#8221;. It also helped a bit that my friend Tom (who I caught up with over Christmas) was suggesting that I should move to Melbourne as well so that we could hang out.</p>

<p>I was cooking dinner on the 29th and felt like I was doing nothing to further the situation. I needed to move out, but my weekend plans weren&#8217;t exactly conducive to that. So I thought &#8220;fuck it&#8221; and sent out a tweet asking if anyone had a place for me to (temporarily) stay in Melbourne.</p>

<p>Tom replied with a half-joking, half-indignant tweet that I should have messaged him first and asked if I could stay there. I sent him a message and he replied and said I could stay at his. The very next day I drove the ~900km down to Melbourne to stay at Tom&#8217;s house.</p>
<hr />
<p>At that point, I had no fucking clue what I was doing in Melbourne. It was one of those spur-of-the-moment things. The drive <em>flew</em> by, thanks in part to the Hume Highway dual-carriageway upgrades and the most-excellent Back to Work podcast.</p>

<p>Then, I got to see Melbourne for the first non-going-through-in-a-bus-to-the-airport-for-railscamp time. This city reminds me so much of San Francisco, from the cafés, to the over-population of hipsters (which is a con, not a pro) to the amazing food and friendly people. <a href='http://rosshill.com.au/melbourne'>Ross Hill actually wrote about these things</a>, and I can totally agree with him. I&#8217;m actually writing this from <a href='http://inspire9.com.au'>Inspire9</a> right now!</p>

<p>I got to experience NYE in Melbourne with some great friends and all of those things combined are what sold me on Melbourne. So I&#8217;m moving there (which is &#8220;here&#8221; right now, but let&#8217;s not get technical).</p>
<hr />
<p>I still had no fucking clue where I wanted to move, but at that point it <em>had</em> to be Melbourne. Some point after that, Tom and I are talking and he brings up that the guy who sold him his apartment (that he shares with two others) had another that he was looking to rent out also.</p>

<p>I got in touch with him, and he showed me the place. It is <a href='http://www.flickr.com/photos/radarlistener/sets/72157628787106371/'>the best place I've ever had the pleasure of looking at</a>. Wooden floorboards, a nice upstairs area, two bathrooms, four bedrooms (one will be used as a study / storage area), gas stove kitchen, nice patio, and so on.</p>

<p>On Friday, I looked it over again with two other prospective housemates and they both agreed that it was nice. One of them backed out due to how long it is out of town, and the other one doesn&#8217;t mind. So I told the agent that I would absolutely love to lease the property.</p>

<p>This morning, I went into the agent&#8217;s office, handed over the first month&#8217;s rent and signed the lease agreement.</p>

<p>I&#8217;ll be moving down and in on the 21st of January. See you around!</p>]]></content>
 </entry>
 
 <entry>
   <title>Matt Lightner</title>
   <link href="http://ryanbigg.com/2011/12/matt-lightner" />
   <updated>2011-12-27T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/12/matt-lightner</id>
   <content type="html"><![CDATA[<p>Matt Lightner &#8211; <a href='http://www.facebook.com/mlightner'>according to posts on his Facebook</a> &#8211; is dead. It apparently happened on Christmas day, which just adds supremely to the suckiness of it all.</p>

<p>You may remember him from that little hosting company called <a href='http://site5.com'>Site5</a> he started when he was 15. You know the one that was one of the, if not <em>the</em> first, hosting company to offer Ruby on Rails support.</p>

<p>I had the pleasure of working with Matt around September last year and ended up visiting him in San Francisco. We went to <a href='http://www.yelp.com/biz/antonios-nut-house-palo-alto'>Antonio's Nut House</a> where we drank and played darts (and ate way too many free peanuts). Then we went back to his apartment where I got to sleep on an air mattress. That morning we went for bagels at a place not too far away from the Nut House. Those are my favourite memories of San Francisco.</p>

<p>He was such an amazing guy and will be terribly missed.</p>]]></content>
 </entry>
 
 <entry>
   <title>Deciding what tests to write</title>
   <link href="http://ryanbigg.com/2011/12/deciding-what-tests-to-write" />
   <updated>2011-12-05T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/12/deciding-what-tests-to-write</id>
   <content type="html"><![CDATA[<p>More people who are new to Ruby are getting into TDD and BDD thanks to the wonderful tools like RSpec and Cucumber that make it easy for them to do so. There&#8217;s no real public information on exactly <em>what</em> you should be testing, though.</p>

<h3 id='testing_validations'>Testing Validations</h3>

<p>RSpec supports the shoulda-matchers gem and I see a lot of people using this to test validations on their models, and this is the <em>first</em> test that they&#8217;re writing. I personally think that this is the wrong way of doing things.</p>

<p>The first test should be one that follows the exact steps that the user would need to do in order to approve this functionality.</p>

<p>In the example test (written in Capybara&#8217;s syntax) below, the user fills in the form (ignoring one of the required fields) and then should see that there&#8217;s an error on the page.</p>

<pre><code>visit root_path
click_link &quot;Posts&quot;
click_link &quot;New Post&quot;

fill_in &quot;Title&quot;, :with =&gt; &quot;Deciding what tests to write&quot;
click_button &quot;Create Post&quot;

within(&quot;#flash_alert&quot;) do
  page.should have_content(&quot;Post could not be created.&quot;)
end

within(&quot;#post_form .errors&quot;) do
  page.should have_content(&quot;Body cannot be blank&quot;)
end</code></pre>

<p>Or if you prefer Cucumber:</p>

<pre><code>Given a user is creating a new post
And the user leaves the post text blank
When the user clicks &quot;Create Post&quot;
Then they should see a validation error:
  &quot;&quot;&quot;
    Body cannot be blank
  &quot;&quot;&quot;</code></pre>

<p>You can imagine the steps that Cucumber would use, they&#8217;d use the Capybara methods just like the original example.</p>

<p>The point is, this test is testing the user&#8217;s interaction with the page, which I think is the most <em>critical</em> part of the application. If the user cannot see this error message, why does it matter if the model validates the presence of this field? <em>It doesn&#8217;t.</em></p>

<p>Testing that the model contains the validation is a secondary thing, and is generally something I skip doing. The test for at least one of the form&#8217;s validations goes into the request spec. If I&#8217;m feeling pedantic I&#8217;ll write another for the other validations, but I can <em>assume</em> that dynamic_form (the thing that provides <code>error_messages_for</code> is doing the right thing when it comes to its own methods. If one error message is showing up, good chance the others are.</p>

<p>In the case where validation error messages <em>don&#8217;t</em> show up then I write a specific test for that inside the request spec before going on to fix it wherever I need to.</p>

<h3 id='testing_complex_logic'>Testing Complex Logic</h3>

<p>In <a href='http://spreecommerce.com'>Spree</a>, there&#8217;s complex logic involved around orders and tracking inventory. This is something I <em>could</em> test with a request spec, but how the system works is made up of so many little parts it makes it slow to test the whole thing:</p>

<ul>
<li>A product exists in the system, has a &#8220;count on hand&#8221; of 1.</li>

<li>A user wants to buy this product, so clicks &#8220;Add to cart&#8221;</li>

<li>A new order is created in the system, with this item</li>

<li>User is prompted to sign in</li>

<li>User is prompted for billing + shipping details.</li>

<li>User is prompted for credit card details</li>

<li>User clicks &#8220;Confirm&#8221; on order page</li>

<li>Order goes through, deducting 1 from &#8220;count on hand&#8221; total, bringing it to 0.</li>
</ul>

<p>A huge portion of these steps aren&#8217;t even required to test the count on hand decreasing. What we care about is that when an order is placed in the system that the count on hand decreases by one. And so this is where a unit test would be better.</p>

<p>This unit test would check that when an order is created, a method such as <code>unstock_items!</code> is called. There would then be another unit test for the actual function of the <code>unstock_items!</code> call, ensuring that it goes through the line items for the order and depletes the stock on the products as necessary.</p>

<p>The unit test is going to be much lighter (and quicker to run!) than the request spec, which is just a massive win.</p>

<h3 id='conclusion'>Conclusion</h3>

<p>At the final retrospective at the CodeRetreat event on Saturday in Sydney, it was brought up that there&#8217;s no &#8220;right&#8221; way to test. Some people thought that testing from the &#8220;bottom-up&#8221; (unit test first, request specs or similar later) was better, but then they saw the merits of testing &#8220;top-down&#8221; (request specs or similar first, then unit tests for the fiddly bits) as well.</p>

<p>I think liberal applications of both of these methodologies is <em>one</em> &#8220;right&#8221; way to test. The more I test, the more I find myself getting better at knowing what to test and how to test it. I can see the merits of both ways. I&#8217;m preferring top-down though, as that&#8217;s, in my opinion, testing what the client is going to be seeing, and that&#8217;s what matters most. If there&#8217;s a bit of gnarly code in there, like the order inventory tracking, then that&#8217;s when I&#8217;d dive down into unit testing.</p>

<p>What are your thoughts on this?</p>]]></content>
 </entry>
 
 <entry>
   <title>Don't print hard-copies</title>
   <link href="http://ryanbigg.com/2011/11/don-t-print-hard-copies" />
   <updated>2011-11-29T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/11/don-t-print-hard-copies</id>
   <content type="html"><![CDATA[<p><a href='http://www.manning-sandbox.com/thread.jspa?threadID=47354&amp;tstart=0'>What a fan-fucking-tasking way to end the day</a>. This honestly <em>really</em> upsets me, because I alone am powerless to do anything to fix this guy&#8217;s problem.</p>

<p>You may know that I <a href='http://manning.com/katz'>wrote a book</a>. I may have written during the process about the difficulties faced and also about how much <em>it fucking rocks</em> to have a book published. I&#8217;ve never felt so damn good for so long.</p>

<p>That&#8217;s a topic for another day. Today&#8217;s a rant kind of day. Tonight, I feel like shit.</p>

<p>Let the rant begin.</p>

<h3 id='authoring_tools'>Authoring tools</h3>

<p>Let&#8217;s start with the authoring tools that Manning provides.</p>

<p>To author a book, you use Manning&#8217;s DocBook format, which isn&#8217;t actually all that bad once you get used to it. Alternatively you could write in Microsoft Word, but I honestly hate it. The documents just feel&#8230; unstructured to me. DocBook appealed to me because I <em>obsess</em> about ordering and structure.</p>

<p>I created all kinds of macros in TextMate for DocBook and was fucking awesome at it towards the end of it. If there were world championships in DocBook, I would place high. Mum would be proud.</p>

<p>Once I had a chapter ready, I had to upload it to Manning&#8217;s system. This is done through an SVN repository. I hate (and I mean, <strong>truly hate</strong>) very few things in this world. Microsoft Word&#8217;s one of them, and SVN is another. Years of abuse have me close to suffering post-traumatic stress disorder attacks every time it so much as conflicts on a damned file.</p>

<p>Anyway, once the file&#8217;s uploaded to Manning&#8217;s system through the version control system from Hell, you get to use the authoring tool also from the same locale. I shit you not, this thing takes <em>4</em> clicks to update a single chapter. You need to click on the gear icon, click on a chapter, scroll down to the god-damned bottom of the page listing all the revisions EVER for the chapter (for God knows what reason) (p.s. there&#8217;s 80+ for some of the earlier chapters, with each revision taking 4 lines of 12pt text) and then click on the radio button for &#8220;Latest&#8221; (the text next to this field doesn&#8217;t trigger it, of course) and then click &#8220;Update&#8221;.</p>

<p>I got majorly annoyed with this process in about June of last year and created my own system in <em>twelve hours</em>. It&#8217;s goal was to a) allow me to publish updates to <em>all the chapters</em> with one command and b) to provide <em>other people</em> with a super-easy way to review the book, and it did both of those things, but it looked like shit. I fixed that with version two, with the help of a friend.</p>

<p>In total, I received ~1,600 notes on the review systems that <em>I built</em> and they contributed back in <em>major</em> ways to the book. Want to know why the book&#8217;s so damned good? Not me. I was just the dude who typed things and put in terrible jokesas footnotes. It&#8217;s the reviewers. They did all the hard work. Honestly. They read the same chapter again and again and hhounded me about problems. One guy and I even used to chat regularly on Skype.</p>

<p>Those guys rock. Over 30 people contributed <em>something</em> to the book. Could&#8217;ve been &#8220;missed a comma&#8221;, could&#8217;ve been &#8220;Prototype sucks!&#8221;. I love them all.</p>

<p>Manning&#8217;s counterpart to this review system also looks like shit, but only allows for the author and Manning staff to have access to the book. On one hand, this is great because it stops the inevitable piracy (which, as far as I know, never happened on my review system), but on the other hand it really sucks because you don&#8217;t get reviews of the book as you go along from people outside your little circle.</p>

<p>So yeah, authoring tools are&#8230; depressing to use. I don&#8217;t think that any publisher has this nailed yet, although I suspect PragProg has gotten the closest to it.</p>

<h3 id='the_one_true_format_but_not_really'>The One True Format (But not really)</h3>

<p>When I started writing the book, I was given a choice. You know this already, but let me refresh your memory just in case you dont: it was DocBook or Microsoft Word. I chose DocBook because it&#8217;s a lovely structured format.</p>

<p>I also thought &#8220;Sure, these guys probably have the tools to convert this into PDF and ePub and Mobi and monetary notes that I can give to people to buy things&#8221;.</p>

<p>Man, I can be naïve sometimes.</p>

<p>When we went to review, they went through the XML document with this tool I can&#8217;t remember the name of and it seriously messed with my <em>obsessive</em> formatting. I was non-plussed. I asked them to fix it, and they did, which was nice of them. Still, this tool basically crapped all over the XML document.</p>

<p>My review system did not. Notes were kept separate from the content and not stored as fucking metadata inside the document itself. Why did I do it this way? <em>Because it&#8217;s sensible</em>. Down the other path lies madness. I know, because I had to live with that.</p>

<p>That was nothing compared with what happened next. To typeset the book they converted the text into a Word document. I don&#8217;t know how exactly they did this (but I suspect it involved the C &amp; V keys on the keyboard, along with a bit of Control). Seriously.</p>

<p>So now what we have is Word document copies of each of the chapters. Word&#8217;s review system is very lol-worthy itself also. As an author, I only really care about one note at a time, not the gazillion that the editor has left on the page and Word loves to display.</p>

<p>This means that to <em>update</em> a chapter, I need to ask Manning for a copy of the chapter <em>as a Word document</em>, which they&#8217;ll <em>email</em> to me, make the fix myself and then <em>email it back to them</em>. Or I use their document management software which was, I&#8217;m sure, designed by people who hate their jobs.</p>

<p>Eventually, enough of these changes will be made and there will be the next for a second printing. When that is, not even I know.</p>

<p>So that lovely little DocBook format I got used to, created all the macros and muscle memory for is now toast. My future is Word documents.</p>

<h3 id='why_printing_technical_books_is_just_a_bad_idea'>Why printing technical books is just a bad idea</h3>

<p>See, with printed books, it&#8217;s really hard to update them. You may have noticed this if you have a copy of Rails 3 in Action on your shelf and open to any page <a href='http://manning.com/katz/errata.html'>listed in the
Errata</a>. Has yours been updated? No? Neither have the three sitting on my bench right now.</p>

<p>There&#8217;s also the problem of this book becoming quickly outdated due to how quickly Rails moves. We actually upgraded the book to Rails 3.1 in May (the book was printed in September), which was practically &#8220;danger close&#8221; to the printing time. I&#8217;m so happy that we got this change in, but I fear for the future.</p>

<p>If the book was kept in a proper, structured electronic format and never printed on dead trees, then we wouldn&#8217;t have this problem. We wouldn&#8217;t have &#8220;Sydney&#8221; misspelt as &#8220;Syndey&#8221; on the back cover because someone could have fixed it and everyone would be happy. Actually, we wouldn&#8217;t have had that if someone didn&#8217;t do a rush-job on the cover, but people make mistakes. It&#8217;s an OK thing to do.</p>

<p>We wouldn&#8217;t run into issues like when Cucumber decides it wants to divorce <code>web_steps.rb</code> and it <em>breaks the whole book</em>. You know why? <em>Because we could update the damn thing</em>. We could release a new update <em>every week</em> if we needed to and people would be happy that it&#8217;s a constantly improving, amazing book.</p>

<p>But instead, we print to dead trees, disabling us from updating it efficiently and easily and it stagnates within 6 months.</p>

<p>Now that we <em>finally</em> (just this week) have the ePub and mobi formats available for the book. I suspected they had to use the afore-mentioned C+V keys to do these too. Updating these is easy in comparison: alter the source, compile a new version, put it on a server and let people know. Done.</p>

<p>And hey, it would be super easy if the source was DocBook and there was a tool to read that XML and convert it into ePub friendly HTML. But there&#8217;s not one in this process.</p>

<p>That&#8217;s how tech publishing should be: electronic only. If you want a dead-tree copy, well, I&#8217;m sorry, but you&#8217;re going to have to print it yourself.</p>

<h3 id='there_will_be_more'>There will be more</h3>

<p>Yeah, we probably did fail at creating The Best Book Ever. But that was never the goal. The goal was to create a book that was easy for noobs to read and learn Rails (and to be the best at <em>that</em>).</p>

<p>I think we succeeded, but I also have a ginormous ego.</p>

<p>Yes, there are mistakes but we will fix them. I will do everything in my power to address any and all (reasonable) concerns you have with the book. I want it to be perfect for you.</p>

<p>There will be updates. Even though Manning&#8217;s tools are not that great, the people who work there are some of my favourite people in the world. I will work with these wonderful people and we will release a wonderful Version Two.</p>

<p>Promise.</p>]]></content>
 </entry>
 
 <entry>
   <title>Screencast: wrong argument type</title>
   <link href="http://ryanbigg.com/2011/11/screencast-wrong-argument-type" />
   <updated>2011-11-23T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/11/screencast-wrong-argument-type</id>
   <content type="html"><![CDATA[<p>I am really surprised at how well-received my <a href='http://ryanbigg.com/2011/10/screencast-pilot/'>Conway's
Game of Life</a> screencast was. Seems that everyone who watched it liked it, which is always a nice thing :)</p>

<p>This week&#8217;s screencast is a slightly more advanced topic: debugging a <code>wrong argument type Module (expected
class)</code> error which was happening inside of the <code>spree_paypal_express</code> Spree extension.</p>

<p>It&#8217;s 28 minutes of debugging goodness and <a href='https://s3.amazonaws.com/ryanbigg_screencasts/002-wrong-argument-type.mov'>you can view it here</a>.</p>
<hr />
<p>The next screencasts I will do are examples of how to do nested attributes within Rails, covering <code>belongs_to</code>, <code>has_many</code> and <code>has_many :through</code> associations, along with demystifying how nested attributes works within Rails.</p>]]></content>
 </entry>
 
 <entry>
   <title>The Rails API</title>
   <link href="http://ryanbigg.com/2011/11/the-rails-api" />
   <updated>2011-11-14T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/11/the-rails-api</id>
   <content type="html"><![CDATA[<p>Recently, the Rails API got a facelift. Gone is the boring and dull blue four-frame-set API that once was. Now we have a dual-framed red API instead. The colours are good, I&#8217;ll give it that. Take a look at it:</p>
<img src='/images/rails-api/original.png' />
<p>Notice anything wrong?</p>

<p>Probably not.</p>

<p>So let&#8217;s take away some things until you start thinking it&#8217;s wrong. How about we take out that &#8220;RDOC_MAIN.rdoc&#8221; string &#8211; both instances &#8211; and we made the version more prominent? We&#8217;ll also get rid of the last modified timestamp, as a date is more friendly to people. Making these simple changes, we&#8217;ll get this:</p>
<img src='/images/rails-api/title-changes.png' />
<p>Right. That&#8217;s a little better now. It&#8217;s clearer what the purpose of this page is and when it was last updated. We don&#8217;t care that the README is in a file called &#8220;RDOC_MAIN.rdoc&#8221;, and so we&#8217;ve removed it. Simple.</p>

<p>Now what else don&#8217;t we need? Well, when we go to the API we&#8217;re most likely going to want to find information about the methods provided by Rails. So why have the README there at all? While it&#8217;s a good placeholder for the content, that&#8217;s all it is: a placeholder. The main focus of the API site should be what we want to do on it: search for things. If you want to read the README, there&#8217;s <a href='http://github.com/rails/rails'>better (and more standard) places for that</a>, quite simply.</p>

<p>With the README gone, we&#8217;re going to have this gigantic void of empty, useless space. With this change, the main feature of the API, the searching, is almost hidden up in the top-left hand corner. So let&#8217;s make that more prominent.</p>

<p>Is that menu underneath it really useful? It contains an awfully large amount of items in it. Do people really care about that? Isn&#8217;t searching for something a much easier way to find it? I&#8217;d say so.</p>

<p>So we remove the README, we remove the menu, we make the search more prominent. What are we left with?</p>
<img src='/images/rails-api/search-box.png' />
<p>The title, the date the API was last updated and a box to search. There&#8217;s no mystery to what this box does: it says &#8220;Search&#8221; on it. It could also say &#8220;Search the Rails API&#8221;. Anybody should be able to figure out that you can search the API using this box.</p>

<p>But there&#8217;s no button! There doesn&#8217;t need to be a button, though. When a person searches, it will autocomplete their search and show the matching results from the API. You could even go a step further and weight certain results, so that things like <s>`ActiveRecord::Base`</s>, um, excuse me, <code>ActiveRecord::FinderMethods</code>&#8217;s <code>find</code> method appears before <code>ActiveResource::Base</code>.</p>

<p>Further more, you could get a search for &#8220;match&#8221; to show the routing (<code>ActionDispatch::Routing::Mapper::Base</code>) <code>match</code> method prominently, and the other <code>match</code> (like the one in <code>HTML::Selector</code>) methods less prominently, perhaps in a grey colour instead of black.</p>

<p>Anything wrong with this now? I think not. The API is less confusing and more prominently displays the function that most people use it for.</p>
<hr />
<p>That&#8217;s my vision for the future of the Rails API. I know it probably won&#8217;t get to that stage, as there&#8217;s large technical hurdles in the way (such as indexing the entire documentation for Rails into a searchable format), but I think that it&#8217;s still possible.</p>

<p>So this weekend I dove into some <a href='http://documentcloud.github.com/backbone/'>Backbone.js</a> with the help of <a href='http://twitter.com/joeybeninghove'>Joey Beninghove's</a> <a href='http://backbonescreencasts.com/'>great Backbone.js screencasts</a> and built this idea. There&#8217;s also a bit of the Twitter Bootstrap in use, which makes things pretty.</p>

<p>It&#8217;s called <a href='http://radar.github.com/sume'>Sume</a> and looks like this:</p>
<img src='/images/sume.png' />
<p>It&#8217;s just a proof-of-concept of this Rails API idea, allowing you to search for only a handful of classes and methods at the moment. But it presents it in a neat format.</p>

<p>Ah, and one more thing: it gives you a unique URL for each page, which is something the current Rails API <em>doesn&#8217;t do</em>. When you make a request to <a href='http://radar.github.com/sume/#search/ActiveSupport::Concern'>the link for
ActiveSupport::Concern</a> it actually takes you right to those docs. This makes it easy to link it to other people.</p>]]></content>
 </entry>
 
 <entry>
   <title>Going on a Spree</title>
   <link href="http://ryanbigg.com/2011/11/going-on-a-spree" />
   <updated>2011-11-03T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/11/going-on-a-spree</id>
   <content type="html"><![CDATA[<p>When I was in America, I had the pleasure of talking to a lot of Americans. Americans are fun. As soon as they hear the Australian accent they say something along the lines of &#8220;Oh, you&#8217;re from Australia?! I <em>love</em> Australia!&#8221;.</p>

<p>While I was there, I was thinking that there&#8217;s just <em>so much</em> work out in the world. So many people doing super interesting things. I started to think that perhaps I should take a break from &#8220;shotgun consulting&#8221; again, but only if I could find one thing that I was super passionate about.</p>

<p>I was courted by so many different companies when I was at GoGaRuco and Strangeloop and while I was in Chicago. Stuff ranging from a joking &#8220;Screw those guys, come work for us!&#8221; to more serious &#8220;We&#8217;ll do whatever it takes you get you on board&#8221;. You know what&#8217;s a really good feeling? Being wanted. It&#8217;s so <em>amazing</em>. So thanks to those companies and their employees for their offers.</p>

<p>While I was in Chicago, I got into some serious-type discussions with two companies. One of them was Groupon, where I sat for about a week doing work remotely for RubyX. I think they have an amazing team at Groupon (including people like Bo Jeanes, who I am very good friends with), but it&#8217;s a bit too large for what I wanted to do.</p>

<p>On the very same day that these serious-type discussions happened with Groupon, the same kind of discussions started with a slightly smaller company called <a href='http://spreecommerce.org'>Spree Commerce</a>. Sean and I started talking about a Community Manager position that he wanted to fill, a position that involves full-time open source work and talking with members of the community seeing to their needs. Spree has <a href='http://techcrunch.com/2011/10/10/spree-raises-1-5-million-from-true-ventures-aol-for-open-source-ecommerce-platform/'>$1.1 million</a> dollars of funding, which will go into some pretty exciting projects.</p>

<p>That is precisely the thing I am passionate about: making a product and the community around it <em>better</em>. Spree has a great platform and it will only get better with time.</p>

<p>For instance, we have <a href='http://groups.google.com/group/spree-user/msg/af44fbdb7e401b8e'>just undertaken work to move all of Spree's functionality into a namespace</a>. This will be merged back into the<code>master</code> branch next week. This means that if you want to have a <code>Product</code> model in your application and still want to use Spree&#8217;s then that&#8217;s entirely possible. I go into more information in <a href='http://groups.google.com/group/spree-user/msg/af44fbdb7e401b8e'>this lengthy post on the Google Group</a> about what the namespacing means.</p>

<p>I&#8217;m excited to start officially at Spree next week and I wish RubyX all the best for their future endeavours. If you want a crack team people to build your Rails application, RubyX is that team.</p>]]></content>
 </entry>
 
 <entry>
   <title>Screencast: Pilot</title>
   <link href="http://ryanbigg.com/2011/10/screencast-pilot" />
   <updated>2011-10-31T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/10/screencast-pilot</id>
   <content type="html"><![CDATA[<p>Today I went out and got myself a microphone so I could begin to do some screencasting. I did some back in February for EngineYard and really enjoyed it and have been wanting to get back into it for a while, but I have been busy writing.</p>

<p>This evening, I <a href='http://ryanbigg.com/screencasts/000-game-of-life.mov'>recorded a 48 minute screencast</a> and how to begin to code a program to do it in Ruby, explaining things as I go along.</p>

<p>You can see the end result on my <a href='https://github.com/radar/screencasts/tree/master/000-game-of-life'>screencasts repository on GitHub</a>.</p>

<p>Please let me know of any feedback you have on this screencast (i.e. was the keyboard too noisy or did I speak too fast?) or any ideas for future ones you&#8217;d be interested in listening to. Ideally, I&#8217;d like to do one every week.</p>]]></content>
 </entry>
 
 <entry>
   <title>That One Test</title>
   <link href="http://ryanbigg.com/2011/10/that-one-test" />
   <updated>2011-10-19T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/10/that-one-test</id>
   <content type="html"><![CDATA[<p>Have you ever worked on a project that has tests? Probably. How about a project that has a test that runs fine by itself but fails when the whole suite runs? Maybe. That&#8217;s what I&#8217;m going to be talking about here today.</p>

<p>You probably already know the story. You have a whole bunch of tests, perhaps hundreds of them, that take multiple minutes to run as a whole and about 32% of the way through <em>one</em> of the test fails. But that&#8217;s ok, because you&#8217;re running <code>rspec</code> with the <code>--fail-fast</code> option which will make RSpec quit the instant it comes across a failure, right?</p>

<p>Or maybe not. Well, now you know.</p>

<p>Anyway, this one test is testing some piece of obscure, but required, functionality. Whenever you try thinking about when you worked on it &#8211; or even <em>if</em> you worked on it &#8211; your mind starts going fuzzy and the room starts to spin widdershins. You run the test by itself and RSpec reports this back:</p>

<pre><code>.

1 example, 0 failures</code></pre>

<p>You put on your &#8220;Challenge Accepted&#8221; face and re-run the tests again, perhaps this time with the <code>--fail-fast</code> option enabled. Sure enough, the test fails again.</p>

<p>Cool story.</p>
<hr />
<h3 id='step_1_dont_panic'>Step 1: DON&#8217;T. PANIC.</h3>

<p>You want to fix this. It&#8217;s 5:30pm. On a Friday. The Friday before a long weekend. The very same Friday you promised someone you&#8217;d be home early. But That One Test is being a <em>complete dick</em> about things.</p>

<p>However, there&#8217;s light at the end of the tunnel: only 32% of the tests need running before the failure is going to happen. RSpec will (as far as I have observed) run the tests in precisely the same order all the time. This means that the other 68% of your test suite can be excluded from the suspect list.</p>

<p>To fix this bug, you&#8217;re going to need a list of all the tests that ran before this test. RSpec doesn&#8217;t provide this functionality, and so you&#8217;re going to have to build it yourself. But it&#8217;s easy! Don&#8217;t Panic.</p>
<hr />
<h3 id='step_2_build_a_list_of_suspects'>Step 2: Build a list of suspects</h3>

<p>You know those pretty little green dots / red Fs / yellow stars RSpec prints out? They&#8217;re all coming from a part of RSpec called the <a href='https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/formatters/progress_formatter.rb'>`ProgressFormatter`</a>. Look, sensible code! If the example passes, it calls <code>output.print green(&#39;.&#39;)</code>. You probably couldn&#8217;t get more sensible than this.</p>

<p>My <em>point</em> is that RSpec uses this as a kind of reporting tool to show you that progress is actually being made. The <em>great</em> thing about this is that you can write your own! With your own tool, you&#8217;ll be able to output to a log what specs are being run and then use this as a base list of suspects.</p>

<p>Create a new file called <code>spec/support/spec_logger.rb</code> and put this content in it:</p>

<pre><code>require &#39;rspec/core/formatters/progress_formatter&#39;
class SpecLogger &lt; RSpec::Core::Formatters::ProgressFormatter

  def example_started(example)
    super
    File.open(&quot;specs.log&quot;, &quot;a+&quot;) do |f|
      f.write(example.location + &quot;\n&quot;)
    end
  end
end</code></pre>

<p>What this does is that it inherits the standard green dots, red Fs and yellow stars from <code>RSpec::Core::Formatters::ProgressFormatter</code> and extends it with a bit of functionality that will log exactly what specs are being run during a test run.</p>

<p>To use this formatter in your next (fast failing) test run, run it using <code>bundle exec rspec spec --require spec/support/spec_logger -f SpecLogger --fail-fast</code>.</p>

<p>Once this command completes, you&#8217;ll have a list of suspects in <code>specs.log</code> at the root of your project.</p>
<hr />
<h3 id='step_3_find_the_perp'>Step 3: Find the perp</h3>

<p>In this <code>specs.log</code> file you should have a list of specs that have been run just recently, with the final one being the one that is failing mysteriously. Now let&#8217;s assume that in the entire test suite there are exactly 100 tests total. With this failure occurring 32% of the way through, it should be failing at the #32 test. This number is important because it&#8217;s equally divisible by two.</p>

<p>However, the locations listed in specs.log are going to have duplicate files, and RSpec only allows you to run multiple files at a time, and not multiple locations within multiple files. This list should be culled to only have one line for each file.</p>

<p>Next, the trick is to take one half of these <em>plus</em> the file containing the failing test and run them together. If you take the first 15 tests and run them in an RSpec command like <code>bundle exec rspec spec &lt;file1&gt; &lt;file2&gt; ... &lt;file15&gt;</code> then you&#8217;ll be able to see a result.</p>

<p>This is <em>exactly</em> the process <code>git bisect</code> uses, or at least what I think it does.</p>

<p>If these tests are failing with these first fifteen, then the failure is most likely caused by one of those tests. If it&#8217;s not, then it&#8217;s in the other half. Re-run the test suite with that half and see if you get a failure there.</p>

<p>When you know which half it is, half it again and keep culling down the list of suspects until you have (ideally) two files: the first will be the one that&#8217;s causing the breakage, and the second one will be the one containing the test that&#8217;s failing.</p>

<p>From there, figure out what test in that first file is causing things to fail. Comment out half the tests, run the two files again. If it passes then it&#8217;s in that half, if it fails then it&#8217;s not. Keep at it until you&#8217;ve distilled it down to the minimum amount of tests possible, which can be as low as two, but there could be a case where two tests in the original file are causing the disruption.</p>
<hr />
<h3 id='step_4_fix_it'>Step 4: Fix it.</h3>

<p>This is left as an exercise to the reader. This could be anything, but at least now you know the area where the code is failing.</p>

<p>Once it&#8217;s fixed, run the entire test suite again to ensure that everything is peachy.</p>

<p>If it is, congratulations. Go home. Enjoy the weekend.</p>]]></content>
 </entry>
 
 <entry>
   <title>Leaving Chicago</title>
   <link href="http://ryanbigg.com/2011/10/leaving-chicago" />
   <updated>2011-10-02T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/10/leaving-chicago</id>
   <content type="html"><![CDATA[<p>I have just spent two weeks in America being reminded what such great people live outside my own country.</p>

<p>This is a story, written in several parts, about my flying experience from Chicago back to Sydney this weekend. I found it entertaining living it, and I hope you find it entertaining reading.</p>
<hr />
<p>I&#8217;m sitting at the gate in Chicago airport and I see this 2 year old girl with her mother, and instantly, fear strikes. The little girl is being perfectly innocent, playing with her toys and giggling. She seems like a little angel, but I know better.</p>

<p>Someone has to sit near that girl, and there&#8217;s a chance (although relatively low) it&#8217;s gonna be me. This fear comes from being&#8230; traumatized&#8230; by other children screaming on planes while I&#8217;ve tried to sleep or kicking the back of my chair. She could be one of those devil children.</p>

<p>So I calm myself down and remind myself of the tiny statistical probability that I&#8217;ll be sitting near her. She seemed fine.</p>

<p>We line up for boarding and I am a ways back in the line from the girl and her mother, thinking that would be the last time I would see the two. I get on the plane and look for my seat 68H, keeping my eyes peeled on the strip above the seats with the numbers. I find row 68 easily enough (yay, sequential numbering!) and then I look down.</p>

<p>The fear came back. There they were, the mother and the daughter. And one spare seat. Just for me. On the aisle. I know how cattle who have been led to the slaughter feel like now. I instantly begin to slide down the wonderful spiral of depression (and into my seat), and then went through the 5 stages of grief in quite rapid succession.</p>

<p>Perhaps everything would be ok. The little girl was handed a bag of things to entertain her and seemed pretty enthralled by the prospect of a Toy Story puzzle. No screams, no crying, no yelling. No kicking seats. I had accepted my fate. I was doomed to sit next to the child for the next 14 hours and perhaps sleep not a wink the entire time. I was&#8230; strangely actually OK with that.</p>

<p>Then a male air host comes by and says the most beautiful words I have heard in my entire trip:</p>

<p>&#8220;Excuse me sir, are you travelling alone?&#8221; &#8220;Yes.&#8221; &#8220;Would you like to move down? I have some spare seats over here you are welcome to.&#8221;</p>

<p>A choir of angels sung in my head, the clouds covering the Chicago sky vanished and my fear turned to joy. I moved down a couple of rows to and was assigned a block of three seats, just for myself, right in front of one of the cabin dividers of the aircraft. I laughed at the absurdity of the situation: my acceptance of my approaching doom (of having to sit next to a toddler) and then being not only rescued by an air host, but also being given three. Whole. Seats. For me.</p>

<p>So thank you, Taka, from the Cathay Pacific Chicago to Hong Kong 3:25pm flight on the 28th September. Very much appreciated.</p>

<p>Oh, and Cathay Pacific have powerplugs on each seat (even back here in cattle class) and plenty of leg room. I think everything&#8217;s going to be alright.</p>

<p>The plane took off and I enjoyed the thought of having three, whole, seats, to myself for the entire flight. After takeoff, I took out my laptop and did some work for a client.</p>
<hr />
<p>Later on, I got up to go to the toilet and on my way back this stranger says in a thick American accent &#8220;Hey buddy, you&#8217;ve got that whole row to yourself up there, right?&#8221; and I confirm. He says: &#8220;Well look, I&#8217;ll do you a deal. I&#8217;ll give you one hundred dollars if you let me swap my seat here for your row&#8221; and he shows me two empty seats (the aisle and the middle seat) back in the plane, about 20 rows back from where I moved to, 10 back from the kid.</p>

<p>I ask, &#8220;is anyone sitting in that middle seat?&#8221; and he says no, so I say &#8220;Deal!&#8221;. He opens the overhead compartment, unzips his bag and pulls out a money clip full of bills, about half a centimeter thick. He leafs through them and hands me $100 in American money.</p>

<p>We go back to my seat and I pack up my things. As I do that we chat about where we both come from, what we are traveling for and where we are going. He says he&#8217;s going to the Philippines and would love to stretch out and sleep on the plane.</p>

<p>&#8220;Pleasure doing business with you!&#8221; I say as I move back in the cabin. &#8220;Same to you!&#8221; he replies.</p>

<p>I take my <em>new</em> new seat, quite pleased that I made $100 by being lucky. I do a bit more coding, watch a movie, take a sleeping pill and promptly pass out, sleeping for about 4 hours.</p>
<hr />
<p>As we are approaching Hong Kong, the lady captain comes over the PA and says (in an authoritative voice that only captains have. They probably have some kind of school for Captain Voice) &#8220;Cabin crew, 30 minutes to landing&#8221;.</p>

<p>More than 30 minutes later we are still in a holding pattern, and the captain comes over the PA again: &#8220;Good evening passengers, due to the windy conditions caused by the typhoon in Hong Kong, the Hong Kong airport is backed up and so we are delayed. We apologize for the delay&#8221;. At this point, I didn&#8217;t know there was a typhoon in Hong Kong. This was also the first time I had ever heard a pilot say &#8220;windy&#8221;. I guess typhoons are kind of like that.</p>

<p>So we hang about in the holding pattern for about 40 minutes more. &#8220;This is the captain again&#8221;, the authoritative voice over the PA announces, obviously stressed or annoyed, &#8220;we are unable to land in Hong Kong tonight&#8221;.</p>

<p>A cacophony of noise starts up. &#8220;We are diverting to Taipei airport due to the backup of planes caused by the typhoon over Hong Kong&#8221;. I think I giggled a little at this point. This flight just got weirder.</p>

<p>An older guy called Jim sitting one row back over my left shoulder started a conversation with me about our flight and reason for travel, as you do when flying. He was a woodcarver going to the Philippines on a business trip and he spoke about the plight that some of his workers had, having to walk many more miles to get wood due to the deforestation happening there.</p>

<p>As we&#8217;re approaching Taipei, the pilot announces &#8220;Cabin crew, 30 minutes until landing&#8221; again. I had a sense of deja vú at this point, like I had heard her said those exact words before.</p>

<p>But I passed time by talking to Jim about programming, dreams and neural pathways in the brain and we landed alright in Taipei. Everyone on the plane did the usual thing of unbuckling their seatbelts the instant that the seatbelt sign was turned off and they stood up to get out their luggage. Jamming up the aisles with a mass of bodies and luggage.</p>

<p>We waited there for about 20 more minutes without moving. During this time Jim and I talk to another passenger, a teenage boy from Taiwan, on his row who was actually connected to Taipei through Hong Kong and this boy was really happy that the plane had diverted, even if everyone else wasn&#8217;t. It would mean that he could just get off here with everyone else, eventually. I certainly wasn&#8217;t happy as I had missed my connecting flight out of Hong Kong back to Sydney by that time (the layover was only an hour and a half), and therefore also the breakfast/lunch I had scheduled with some international friends who were arriving at the same time, or near enough.</p>

<p>The captain came over the PA yet again, annoyed still, and said &#8220;There&#8217;s been a change of plans. We are now in the process of refuelling this aircraft and changing the crew. We are now going to attempt to fly <em>back</em> to Hong Kong and land there. We really apologise for any inconvenience that this has caused you. We will inform you of your options when we get you to Hong Kong.&#8221; An American guy behind me sighed loudly and whined that he only wanted to get outside so he could smoke. Long haul flights and smokers aren&#8217;t compatible, it seems. He caught a passing flight attendant who quickly dismissed him with a short &#8220;no&#8221;. He said it was worth a try and continued talking with Jim and I as everyone begun putting their bags back up in the overhead compartment to prepare for the flight back to Hong Kong.</p>

<p>I had wrote the first part (the part about the little girl) of this post on my phone as kind of a short blog post which I thought was an interesting story. I never thought it would turn into this!</p>

<p>So to recap: I&#8217;ve been paid $100 to swap seats with a random stranger, missed my connecting flight to Sydney through Hong Kong, met a couple of new temporary airfriends and have no idea when we&#8217;re going to Hong Kong or when I will finally get back into my nice, comfortable bed in Sydney. At this stage, it certaintly feels it would be easier just to stay in Taipei on a permanent basis. I hear the people here are nice.</p>
<hr />
<p>The plane, with fresh crew and unfresh passengers, left Taipei airport somewhere between an hour and two hours after it arrived there and flew back to Hong Kong. We were stuck in the holding pattern again and the new captain, this time a guy, came over the PA: &#8220;We&#8217;re stuck in a holding pattern over Shenzhen waiting to get into Hong Kong airport. Due to the typhoon, there&#8217;s a large number of planes waiting to land in Hong Kong at this time.&#8221; mhm. Heard it all before, buddy.</p>

<p>But eventually, we did land. It was just after 1am. As soon as we landed, everyone on the aircraft performed that perfect Pavlovian response to the seatbeat sign again and crowded up the aisles. After a couple of minutes of waiting, the pilot comes over the PA again and says: &#8220;Uhh&#8230; we currently have nobody to operate the airbridge in the airport. We&#8217;re going to be waiting a few more minutes for someone to do that. Please wait.&#8221; Massive sighs and a couple of bouts of nervous laughter spread through the cabin.</p>

<p>About 10-20 minutes later we all get off the plane and we are all directed to wait outside the gate, where the crew are giving directions to people who need them. Eventually, we&#8217;re lead away from the gate area and down towards the Transfer area in the airport. Along the way, there&#8217;s <em>hundreds</em> of extremely-tired looking people who are just sitting on the ground or milling about, waiting for their flights. I had an urge to ask them how long they&#8217;d been waiting for, but didn&#8217;t ask. That was silly.</p>

<p>What happened next was an utter disaster. I <a href='https://twitter.com/ryanbigg/status/119460363082272768'>tweeted</a> <a href='https://twitter.com/ryanbigg/status/119462039927275520'>about</a> <a href='https://twitter.com/ryanbigg/status/119470295315787776'>my</a> <a href='https://twitter.com/ryanbigg/status/119477977850449920'>experiences</a> <a href='https://twitter.com/ryanbigg/status/119502614214881280'>during the</a> <a href='https://twitter.com/ryanbigg/status/119507918491103232'>whole thing</a> thanks to the free airport wi-fi. Probably the only thing that kept me relatively sane / calm through the entire debacle.</p>

<p>Our &#8220;tourguide&#8221;, a short, young Asian man, directed us to an empty spot by a shop and told us to wait 20 minutes. He said he needed to go to Head Office to get some clarification on what would happen. We waited for over an hour, perhaps two, and he didn&#8217;t come back.</p>

<p>After that, I lined up in one of the impossibly slow lines that looked vaguely like it was going in the direction of the Cathay Pacific desks. Where you would normally expect an orderly queue would flow into an orderly counter area with a 1:1 ratio on clerk to passenger, actually formed into this zombie-mosh-pit of tired travellers. As I was waiting in the line, the Woman and Child came through and actually pushed in front, about 8 people ahead. I was a little angry, but too tired to really care at that stage.</p>

<p>I waited for 3 hours in that line, speaking to various travellers about their plans and backgrounds to keep myself entertained. When I got to the front of the line I actually realised I was also the back of the line. The other people who had been behind me had obviously either pushed in front or had found alternative ways out. The guy behind the counter looked absolutely exhausted and I thanked him greatly for his work. He assigned me a ticket for a flight out of Hong Kong at 9am the next morning, as well as two $40HK vouchers for spending in the airport as a consolation for the flight delays.</p>

<p>I looked around for some seats to crash on but a couple of hundred other people had the same idea as me, so I was relegated to sleeping on the ground which was basically slightly furry concrete. An airline had handed out &#8220;consolation blankets&#8221; (<a href='https://twitter.com/ryanbigg/status/119513953096306688'>my name, not theirs</a>), thin airline blankets that people could use if they needed to. I grabbed one and used it as a base.</p>

<p>When I laid down, I noticed two buff black guys near me with deep South African accents were talking. I thought they would eventually fall asleep, and was proven wrong over the course of the next three hours. Every time I tried to fall asleep one of them would laugh or raise their voice and I would be alert again. At about 6:30 I gave up on trying to sleep and listened to their conversation. Surprisingly, they were fashion designers from South Africa. They just didn&#8217;t look like the fashion designer type to me.</p>

<p>I rolled out of bed at around 7ish and went upstairs to get some breakfast. I had no idea what exactly my vouchers could buy, so I bought McDonalds as a safety. It was McDonalds, and approximated food well enough that my stomach was not wanting to detach itself and go hunt on its own. Upstairs was packed with bleary-eyed people, probably the same people from the night before who had also missed their connecting flights.</p>

<p>After &#8220;breakfast&#8221;, I made my way to the gate and set an alarm incase I fell asleep. Thanks to the wonderful sunshine streaming in through the Hong Kong airport there was no chance of that. Eventually 9am came around and I got onto the plane, absolutely tired out of my brain. When I sat down, I felt alright, but later on when I went to the toilet again I looked in the mirror and my eyes were bloodshot and I looked the most tired I had seen myself in years.</p>

<p>The flight back to Sydney was non-eventful, apart from some children on the same row as me playing with the blinds the entire flight, opening them and letting in the &#8220;lovely&#8221; sunshine while I tried to sleep. Oh, and the absolutely cute Polish chick with the bright-green eyes sitting a row back. But at least I slept. We arrived fine. No holding patterns, no typhoon bullshit, just flying as it should be.</p>

<p>I was overjoyed to arrive at the baggage claim to see my bag there. I was worried that it may have not made the flight, but it seems these airline people know what they&#8217;re doing when it comes to planes and things. Surprise!</p>

<p>After catching a cab back home, I took a shower and brushed my teeth. Then I got into bed. Wow. That was such an amazing feeling. I cannot describe it. It had felt like I had wanted, nay, <em>needed</em> to lay in this bed for an eternity and was finally only getting to it. That was kind of the case. 40 hours in-transit is an eternity.</p>

<p>Now I&#8217;m back in Sydney and have just about adjusted back to the fact that it has sunshine at the correct times, ready to throw myself back into doing Real Work(tm) and whatever life can throw at me in Sydney.</p>

<p>America was fun and I&#8217;m already making plans to go back there again. But probably not this year, as <a href='http://rubyc.eu/speakers'>I've got a conference on in the Ukraine I have been invited to speak at</a> in November, and I would like to do a little bit of touring around my own country (Australia) in December. We&#8217;ll see.</p>]]></content>
 </entry>
 
 <entry>
   <title>Learning and Asking</title>
   <link href="http://ryanbigg.com/2011/09/learning-and-asking" />
   <updated>2011-09-07T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/09/learning-and-asking</id>
   <content type="html"><![CDATA[<p>Today, I read <a href='http://495west.com/post/9885249988/the-wrong-question-i-want-to-learn-to-code-what?73331330'>this post</a> which discusses what the right question alternative to &#8220;I want to learn to code, what should I do?&#8221;. This post begins with this claim:</p>

<blockquote>
<p>If you want to learn to code and build stuff and you&#8217;re starting by asking someone else what you should do, you&#8217;re already thinking about it the wrong way.</p>
</blockquote>

<p>I think differently to this person. I think that you should be asking people what you&#8217;re doing, but not necessarily just anybody. For instance, you would not ask your grandmother what the latest and greatest changes are in Rails 3.1. You should do some research in the programming language you want to learn and ask <em>those</em> people. IRC channels, Stack Overflow, hell, even find the emails from people in the community and contact them directly. But please do this last part politely and with regard that those people are doing other things as well.</p>

<p>Jared&#8217;s post continues on by recommending to Google things:</p>

<blockquote>
<p>Go to Google and start asking questions. You want to make a webpage? Ask. You want to know what the different coding languages are and which you should learn? Ask.</p>
</blockquote>

<p>Again, I &#8220;think differently&#8221;. Going to Google and entering &#8220;Learn [programming language]&#8221; will give you <em>okay</em> results, but they won&#8217;t be the <em>best</em> results you can get. This is what the people in the community will be able to tell you better than any search engine that is catering for the masses. For instance, the search engine doesn&#8217;t know that you&#8217;ve got experience with another language, and so isn&#8217;t catering for that. If you tell <em>real, knowledgable people</em> this, they&#8217;ll probably recommend something different than if you were, say, a complete newbie to computer programming.</p>

<p>In the first and possibly also for the second case, for Ruby, I would recommend <a href='http://manning.com/black2'>The Well-Grounded Rubyist</a> by David A. Black. It&#8217;s a book that teaches you Ruby from the ground-up. Most <em>definitely</em> in the second case I would recommend <a href='http://pine.fm/LearnToProgram/'>Learn to Program</a> by Chris Pine. <em>If you read both these books you will gain a solid understanding of Ruby</em>. Promise!</p>

<p>Once you&#8217;ve got this basic understanding, then you will know what terms to Google for. Googling right from the beginning, from knowing <em>nothing</em> is akin to googling &#8220;Red lump on leg&#8221; and expecting it to diagnose your problem. Chances are Google&#8217;s going to inevitably lead to a cancer diagnosis. But, if you go speak to an expert in this particular field, like a dermatologist or a doctor at a clinic, they&#8217;re going to give you <em>so much better information</em>.</p>

<p>Please, do not Google to learn a language. The way to learn a language is to get your hands on as much reading material / exercises / screencasts that you can, follow the bouncing ball with them and then finally when you feel comfortable, go out and experiment on your own projects. If you break something, so what? Experiment some more and see if you can fix it. Push the boundaries of your knowledge and never, ever be afraid to be wrong, or even to admit it. Then, and only then, when you&#8217;re <em>completely</em> stuck on something, ask somebody who knows the language.</p>

<p>Also: ever see a cool feature in an application somewhere? Figure out how it works. Pull it apart and investigate that. You <em>will</em> learn something.</p>

<p>You will only get better with practice and experimentation <em>with the language</em> you want to learn, not basing your knowledge off what Google (of all things!) tells you.</p>]]></content>
 </entry>
 
 <entry>
   <title>With Rails 3.1, comes great things</title>
   <link href="http://ryanbigg.com/2011/09/with-rails-3-1-comes-great-things" />
   <updated>2011-09-04T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/09/with-rails-3-1-comes-great-things</id>
   <content type="html"><![CDATA[<p>This is the first blog post I&#8217;ve put up here in nearly three months. Considering that I&#8217;ve posted <em>at least once a month</em> since May &#8216;07, that&#8217;s some sort of record. Since I last posted, a lot has happened. In no particular order&#8230;</p>

<p>I bought a real bicycle. I blame it for my lack of blog posts and increased fitness levels. I am a nerd, goddammit. I&#8217;ve been using to explore Sydney and heckle pedestrians more now that I am not spending weekends writing <em>all the time</em>. In similar news, I&#8217;ve lived in Sydney for a year and a half and today was the first day I went to Wentworth Falls. A++, would hike again.</p>

<p>Then there was all this:</p>

<p><a href='http://weblog.rubyonrails.org/2011/8/31/rails-3-1-0-has-been-released'>Rails 3.1 was released</a> <em>on schedule</em>. Amazing work by amazing dudes. This means that&#8230;</p>

<p>I have finished writing <a href='http://manning.com/katz'>Rails 3 in Action</a> and there will be dead trees copies at StrangeLoop conference in St Louis, where I will be in attendance and signing it. (God, that sounds so pretentious.) I honestly don&#8217;t think I&#8217;ve heard someone say &#8220;this is total bollocks&#8221; (or something along those lines), but perhaps I am selective of hearing.</p>

<p>You will get your dead-tree copies also when Manning can ship them out. I don&#8217;t have any information on these dates at the moment. Updates to the PDF coming shortly, after the typesetters have performed their magic.</p>

<p>I helped out with the now-fantastic <a href='http://guides.rubyonrails.org/asset_pipeline.html'>Official Asset Pipeline</a> guide that explains the ins-and-outs of the Asset Pipeline with Rails 3.1. Thanks to Mohammad Typaldos, Richard Hulse, and the other people who have worked on it since we first published it on this site.</p>

<p>I begun work on <a href='http://github.com/radar/muse'>a documentation tool called "Muse"</a>, the idea <em>and</em> name I &#8216;borrowed&#8217; from my co-author, Yehuda Katz and this lets me do things like <a href='https://github.com/radar/guides/blob/master/sprockets/sprockets.markdown'>an internals guide to Sprockets</a>. Muse parses <a href='https://raw.github.com/radar/guides/master/sprockets/sprockets.muse'>the source file</a> for this guide, validates that it contains correct code examples and then renders it into lovely Markdown.</p>

<p>Ideally, I would like this to work with the Rails guides too eventually, so we could test that its content is still relevant.</p>

<p>Now that the book is done, I will be focussing my efforts on completing that internals guide whenever I find myself with too much spare time and don&#8217;t feel like going for a ride or hiking in the mountains.</p>]]></content>
 </entry>
 
 <entry>
   <title>Sprocket asset tags internals</title>
   <link href="http://ryanbigg.com/2011/06/sprocket-asset-tags-internals" />
   <updated>2011-06-19T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/06/sprocket-asset-tags-internals</id>
   <content type="html"><![CDATA[<p>Yesterday&#8217;s post and twitter bitching caught the eye of our <a href='http://twitter.com/dhh'>fearless leader</a> who basically claimed <a href='https://twitter.com/#!/dhh/status/81987522766450688'>that I've not made documentation patches recently</a>. I responded with a small reminder that I&#8217;ve done <a href='https://twitter.com/ryanbigg/status/81988004947828736'>some documentation work</a> and went a step further and begun an <a href='http://ryanbigg.com/guides/asset_pipeline.html'>Asset Pipeline Guide</a> because I could. I could have pulled the whole &#8220;Don&#8217;t you know who I am?!!&#8221; faux-lebrity deal, but I thought I would be humble. Append &#8220;for a change&#8221; to the end of the previous sentence, if you wish.</p>

<p>That was incredibly fun. We should do it again some time. Have your people call my people, we&#8217;ll do lunch.</p>

<p>Before all that went down, I created a short (by my standards, anyway) <a href='https://gist.github.com/1032696'>Gist about how the `Sprockets::Railtie` class is currently set up in Rails</a>. This little Gist begun as short note taking for myself and I thought that maybe other people would find the information helpful, so I formatted it all pretty like.</p>

<p>After the <em>battle of the egos</em> took place, I delved a little deeper into the Sprockets rabbit hole, got defeated by some gnarly code and thought &#8220;fuck it dude, let&#8217;s go <s>bowling</s> to sleep&#8221;. I awoke this morning and delved a little deeper into exactly how all of this magic happens.</p>

<p>This guide now lives as the <a href='https://github.com/radar/guides/blob/master/sprockets.md'>Sprockets Internals Guide</a> on my <a href='http://github.com/radar/guides'>guides</a> repository. Check out both of them. You may learn something.</p>]]></content>
 </entry>
 
 <entry>
   <title>The Asset Pipeline</title>
   <link href="http://ryanbigg.com/2011/06/the-asset-pipeline" />
   <updated>2011-06-18T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/06/the-asset-pipeline</id>
   <content type="html"><![CDATA[<p>Today I begun writing the section that I&#8217;ve deemed should be at the beginning of Appendix B (&#8220;Tidbits&#8221;) of Rails 3 in Action. It&#8217;s about the asset pipeline stuff that has been brought into Rails 3.1 with the aid of the Sprockets gem. I&#8217;ve decided to put it at the beginning of this Appendix as it&#8217;s probably the most interesting thing in the entire appendix and it hasn&#8217;t been written about in this much detail (at least, from what I&#8217;ve seen) before.</p>

<p>So far, it&#8217;s looking good. I cover things like:</p>

<ul>
<li><code>image_tag</code> generating a URL such as <code>/assets/image.png</code> which actually is served through Sprockets.</li>

<li>Assets can be at either <code>app/assets</code> or <code>vendor/assets</code>. No mention of <code>lib/assets</code> because I don&#8217;t think it&#8217;s sensible to put assets in <code>lib</code>. Maybe someone can explain that one to me.</li>

<li>By inheriting from <code>Rails::Engine</code> within a gem, that gem&#8217;s <code>app/assets</code> subdirectories are now added to the load path for Sprockets. When Sprockets goes looking for an asset, it will look there, providing the directories exist. Also, <code>vendor/assets</code>, ditto.</li>

<li>Sprockets directives. Not even the <em>Sprockets README, Wiki or <a href='http://getsprockets.org/'>site</a></em> cover this. You would have thought it&#8217;s kind of a, you know, <em>core behaviour that people would wet their pants over</em>, but obviously not given the lack of documentation.</li>

<li>Pre-compiled Sass, SCSS and CoffeeScript and how their relative gems (<code>sass-rails</code> and <code>coffeescript</code>) aid in that purpose, and how they&#8217;re served through Sprockets.</li>
</ul>

<p>But the final thing that I want to cover is how it all works in the <code>production</code> environment. From what I can see, assets are given an MD5 identifier (<code>application.css</code> becomes <code>application-23daf...</code>) for some mysterious purpose and they are cached <em>somewhere</em>. So I went looking for information that explains it. Surely Sam Stephenson or <em>someone</em> else who&#8217;s worked on this <em>amazing new core feature</em> for Rails 3.1 has written <em>something</em> about it.</p>

<p>Right?</p>

<p>No. This is a feature that has been packed into Rails 3.1 with no rationale other than hearsay to back it up. The Rails Core team deemed it would be a fabulous idea to have an asset manager within Rails 3.1, and boom, there it was. I&#8217;m sure they would have gone with Jammit if only it had been created by a 37signals employee. Oh well, at least Sprockets is.</p>

<p>Jammit is exceptionally well documented and has a group of people who are already using it. Again, this whole <em>rationale</em> business comes into play. There&#8217;s no clearly laid out rationale why the Rails Core Team chose to go with Sprockets rather than Jammit. We can circulate rumours and hearsay (like the one above about it being made by a 37signals employee being the reason it was picked) all we like, but it&#8217;s not until there&#8217;s an actual official piece of documentation that says &#8220;this is why things are the way they are&#8221; that we are (usually) satisfied.</p>

<p><a href='http://gembundler.org'>Bundler&#8217;s site</a> is a <strong>fantastic</strong> example of great documentation. Hell, it even provides a <a href='http://gembundler.com/rationale.html'>rationale</a> that explains how it works and why it works in pretty easy-to-understand terms.</p>

<p><em>[breath]</em></p>

<p>So where do people who want to know about Sprockets go to learn about the rationale of why it is bundled with Rails 3.1? How about the location of any documentation about how to disable it or configure it any way? Well, that was <a href='https://github.com/lifo/docrails/commit/0fd52bb6c79f20b8dbd5c8afb774ef1dae155fc4'>added by yours truly</a> earlier today. I also wrote up <a href='https://gist.github.com/1032696'>some notes</a> just so I could understand how the <code>Sprockets::Railtie</code> works for myself. Thought others may find it useful too.</p>

<p>Not documenting things makes it <em>incredibly</em> hard for anybody else to understand what the hell you&#8217;re trying to do and provides no justification for anybody viewing your project as to why they should use it. Any single person can throw code up online. It takes someone special to make people understand why it&#8217;s there and why they should <em>want</em> to use it.</p>

<p>I think it&#8217;s great that there&#8217;s new features being added to Rails and old ones being reworked. But, I think it&#8217;s absolute crap that there&#8217;s no go-to source of explaining why these things exist and how they make our lives better. <em>I</em> certainly understand how Sprockets makes my life easier, but someone else <em>might not</em>. I don&#8217;t want to have to explain to those people every single time they ask &#8220;Why should I use sprockets?&#8221; my reason for using it. I want to be able to say &#8220;I read this guide <span>link</span> and it really helped me understand it. Perhaps you&#8217;ll understand too?&#8221;</p>

<p>It&#8217;s just so incredibly hard trying to explain something in the book when there&#8217;s just <em>no</em> reference material to go by or anybody else to ask.</p>

<p>For without this documentation / reference material, the people in search of it write ranty blog posts. And we don&#8217;t want that.</p>]]></content>
 </entry>
 
 <entry>
   <title>Mac OS X, Ruby, RVM, Rails and You</title>
   <link href="http://ryanbigg.com/2011/06/mac-os-x-ruby-rvm-rails-and-you" />
   <updated>2011-06-06T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/06/mac-os-x-ruby-rvm-rails-and-you</id>
   <content type="html"><![CDATA[<p>
  <strong>This beginner's guide will set up with Ruby 1.9.2, RVM and Rails 3.0.7 and is specifically written for a <em>development</em> environment on Mac OS X, but will probably work on many other operating systems with slight modifications.</strong>
</p><p>This guide is <em>almost</em> a copy of my older <a href='http://ryanbigg.com/2010/12/ubuntu-ruby-rvm-rails-and-you/'>Ubuntu, Ruby, RVM, Rails and You</a> guide, but it's written primarily for Mac OS X.</p><p>
  If you're looking for a quick-n-dirty way, then try <a href='https://github.com/wayneeseguin/rvm/raw/master/contrib/bootstrap_rails_environment'>Wayne E. Seguin's rails_bootstrap_script</a> which probably gets a version of Rails working for you, albeit with 1.8.7 rather than 1.9.2.
</p>
<p>This guide will go through installing the <a href='http://rvm.beginrescueend.com'>RVM (Ruby Version Manager)</a>, then a version of Ruby (1.9.2), then <a href='http://rubyonrails.org'>Rails</a> and finally <a href='http://gembundler.com'>Bundler</a>.</p>

<p>By the end of this guide, you will have these things installed and have some very, very easy ways to manage gem dependencies for your different applications / libraries, as well as having multiple Ruby versions installed and usable all at once.</p>

<p>We assume you have <code>sudo</code> access to your machine, and that you have an understanding of the basic concepts of Ruby, such as &#8220;What is Rubygems?&#8221; and more importantly &#8220;How do I turn this computer-thing on?&#8221;. This knowledge can be garnered by reading the first chapter of <a href='http://manning.com/black2'>any Ruby book</a>.</p>
<h3>Housekeeping</h3>
<p>The first thing we&#8217;re going to need to install is XCode, which can be found on the second DVD of your install disks or, alternatively, on the Mac App Store for $5. It&#8217;s a big download, so you may want to find the DVDs again. We&#8217;re going to need this for the build tools that it installs to install Ruby and other packages.</p>

<p>First of all, we&#8217;re going to need to install some package management script so that we can install packages such as Git, MySQL and other things exceptionally easy. The best package management system on Mac OS X for this is <a href='https://github.com/mxcl/homebrew'>homebrew</a>. We can install this by using this command:</p>

<pre><code>ruby -e &quot;$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)&quot;</code></pre>

<p>Once it&#8217;s installed, we&#8217;ll be able to install the package for <a href='http://git-scm.org'>Git</a> by using a simple command like this:</p>

<pre><code>brew install git</code></pre>

<p>We&#8217;ll need Git to install RVM as it clones it from <a href='http://github.com/wayneeseguin/rvm'>RVM's GitHub repository</a>.</p>
<h3>RVM</h3>
<p>RVM is a <a href='http://rvm.beginrescueend.com'>Ruby Version Manager</a> created by Wayne E. Seguin and is extremely helpful for installing and managing many different versions of Ruby all at once. Sometimes you could be working on a project that requires an older (1.8.7) version of Ruby but also need a new version (1.9.2) for one of your newer projects. This is a problem that RVM solves beautifully.</p>

<p>Another situation could be that you want to have different sets of gems on the same version of Ruby but don&#8217;t want to have to do deal with Gem Conflict Hell. RVM has <a href='http://rvm.beginrescueend.com/gemsets/basics/'>gemsets</a> for this. <strong>This is a feature you wouldn't have if you used the packaged Ruby</strong>.</p>

<p>We&#8217;re going to use it to install only one version of Ruby, but we can <a href='http://rvm.beginrescueend.com'>consult the documentation</a> if we want to install a different version of Ruby.</p>

<p>With <code>git</code> and <code>curl</code> installed we&#8217;ll be able to install RVM with this command:</p>

<pre><code>bash -s stable &lt; &lt;(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) </code></pre>

<p>The beautiful part of this is that it installs Ruby to our home directory, providing a sandboxed environment just for us.</p>

<p>Once that&#8217;s done, we&#8217;re going to need to add a line to <code>~/.bashrc</code> file (the file responsible for setting up our bash session) which will load RVM:</p>

<pre><code>echo &#39;[[ -s &quot;$HOME/.rvm/scripts/rvm&quot; ]] &amp;&amp; source &quot;$HOME/.rvm/scripts/rvm&quot;&#39; &gt;&gt; ~/.bash_profile </code></pre>

<p>Then we&#8217;ll need to reload the <code>~/.bashrc</code> file which we can do with this small command:</p>

<pre><code>. ~/.bash_profile</code></pre>

<p>If we run <code>rvm notes</code> we&#8217;ll be told the certain things that we need to have installed to install the different versions of Ruby:</p>

<pre><code>Notes for Darwin ( Mac OS X )
    For Snow Leopard be sure to have Xcode Tools Version 3.2.1 (1613) or later
    You should download the latest Xcode tools from developer.apple.com.
      (This is since the dvd install for Snow Leopard contained bugs).

    If you intend on installing MacRuby you must install LLVM first.
    If you intend on installing JRuby you must install the JDK.
    If you intend on installing IronRuby you must install Mono (version 2.6 or greater is recommended).</code></pre>

<p>We&#8217;re not going to be using MacRuby, JRuby or IronRuby in this guide so we won&#8217;t need to install any of those things. If we have XCode installed we will have everything we need to install Ruby.</p>

<p>Now our Ruby lives will be as painless as possible.</p>
<h3>Ruby</h3>
<p>With RVM and XCode installed we can install Ruby 1.9.2:</p>

<pre><code>rvm install 1.9.2</code></pre>

<p>This command will take a couple of minutes, so grab your $DRINKOFCHOICE and go outside or something. Once it&#8217;s done, we&#8217;ll have Ruby 1.9.2 installed. To begin using it we can use this lovely command:</p>

<pre><code>rvm use 1.9.2</code></pre>

<p>Are we using 1.9.2? You betcha:</p>

<pre><code>ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]</code></pre>

<p>Or, even better, would be to make this the <em>default</em> for our user! Oooh, yes!</p>

<pre><code>rvm --default use 1.9.2</code></pre>

<p>Now whenever we open a new bash session for this user we&#8217;ll have Ruby available for us to use! Yay!</p>
<h3>Rails</h3>
<p>Now that RVM and a version of Ruby is installed, we can install Rails. Because RVM is installed to our home directory, we don&#8217;t need to use that nasty <code>sudo</code> to install things; we&#8217;ve got write-access to our own things! To install the Rails gem we&#8217;ll run this command:</p>

<pre><code>gem install rails</code></pre>

<p>This will install the <code>rails</code> gem and the other 22 gems that it and its dependencies depend on, including Bundler.</p>
<h3>MySQL</h3>
<p>If you&#8217;re planning on using the <code>mysql2</code> gem for your application then you&#8217;ll want to install the <code>mysql</code> Homebrew package using this command:</p>

<pre><code>brew install mysql</code></pre>

<p>If you&#8217;re using Rails 3.0 then you&#8217;ll need to specify a 0.2.x version of the <code>mysql2</code> gem in your Gemfile:</p>

<pre><code>gem &#39;mysql2&#39;, &#39;~&gt; 0.2.7&#39;</code></pre>

<p>If you&#8217;re using Rails 3.1, then this line will get it:</p>

<pre><code>gem &#39;mysql2&#39;</code></pre>
<h3>PostgreSQL</h3>
<p>If you want to use PostgreSQL instead of MySQL:</p>

<pre><code>brew install postgresql</code></pre>

<p>Then in the application&#8217;s <code>Gemfile</code> use the <code>pg</code> gem:</p>

<pre><code>gem &#39;pg&#39;</code></pre>
<h3>Fin.</h3>
<p>And that&#8217;s it! Now you&#8217;ve got a Ruby environment you can use to write your (first?) Rails application in with such minimal effort. A good read after this would be the <a href='http://guides.rubyonrails.org'>official guides for Ruby on Rails</a>. Or perhaps the documentation on the <a href='http://rvm.beginrescueend.com'>RVM site</a> which goes into using things such as <a href='http://rvm.beginrescueend.com/gemsets/basics/'>gemsets</a> and the exceptionally helpful <a href='http://rvm.beginrescueend.com/workflow/rvmrc/#project'>per-project .rvmrc file</a>. A quick way to generate an <code>.rvmrc</code> file is to run a command like this inside the project</p>

<pre><code>rvm use 1.9.2@rails3 --rvmrc</code></pre>

<p>RVM is such a powerful tool and comes in handy for day-to-day Ruby development. Use it, and not the packages from apt to live a life of development luxury.</p>]]></content>
 </entry>
 
 <entry>
   <title>A potential use for asset pipelining</title>
   <link href="http://ryanbigg.com/2011/06/a-potential-use-for-asset-pipelining" />
   <updated>2011-06-01T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/06/a-potential-use-for-asset-pipelining</id>
   <content type="html"><![CDATA[<p>So I&#8217;ve been thinking a lot recently about the changes in Rails 3.1, particularly the asset pipelining stuff, engines and how magical precisely gems are. I&#8217;m combining these last two into a <a href='http://github.com/radar/forem'>kick-ass forum engine for Rails 3.1</a> that you may have heard about already. Its name is a terrible pun and I am proud of it. I do like puns.</p>

<p>Anyway, asset pipelining! So I wanted to add theming support to forem because it&#8217;s butt-ugly right now and I can&#8217;t design for crap. Have you seen this blog? I wanted to make theming so dead-simple for forem that people just need to put one or two lines in their application and <em>BLAMMO</em> it would work.</p>

<p>I have accomplished this goal tonight, in what was probably about 10 minutes of thinking, experimenting and saying &#8220;wow, I can&#8217;t believe it works&#8221; when it actually worked. To make theming work on forem, it&#8217;s as simple as putting this line in your <code>Gemfile</code> (<em>after</em> the <code>forem</code> gem, as it needs to be loaded first):</p>

<pre><code>gem &#39;forem-theme-base&#39;, :git =&gt; &quot;git://github.com/radar/forem-theme-base&quot;</code></pre>

<p>This gem is actually its own Rails engine, which means that it gets all the goodies that a Rails engine is bestowed, including the automatic hooks to the asset pipelining. This gem also contains this line:</p>

<pre><code>Forem::Engine.theme = :base</code></pre>

<p>This (obviously) tells forem what theme to use, and can be overriden at your wish if you had multiple themes. I am considering having a settings panel for this in the backend.</p>

<p>To actually style the forum you&#8217;ll need to put this line in the layout that forem uses:</p>

<pre><code>&lt;%= forum_theme_tag %&gt;</code></pre>

<p>I would make this happen automatically, but other people may wish to apply their site&#8217;s styles to the forum system without having to create another gem, and so I leave this as optional. This little tag generates a <code>stylesheet_link_tag</code> like this:</p>

<pre><code>&lt;%= stylesheet_link_tag &quot;assets/forem/base/style.css&quot; %&gt;</code></pre>

<p>Rails then will know where to serve this from because <code>forem-theme-base</code> is an engine.</p>

<p>Dead simple, and utterly amazing. Rails 3.1 is awesome.</p>]]></content>
 </entry>
 
 <entry>
   <title>The Richest</title>
   <link href="http://ryanbigg.com/2011/05/the-richest" />
   <updated>2011-05-23T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/05/the-richest</id>
   <content type="html"><![CDATA[<p>Long, long ago in this very galaxy I used to write fiction. If you dig long enough and hard enough on the internet you&#8217;ll find it. I won&#8217;t link to it here because, to be honest, I am embarrassed by it for no particular reason. Some said it was good, but I think they were just being kind.</p>

<p>On the last day of Railsconf, a group of us went out to dinner. Somehow, the topic of &#8220;The Richest Man Alive&#8221; came up and basically the entire evening was spent coming up with hilarious fictional scenarios and repeating the best of them where the Rich guy is asked by his butler &#8220;Sherry?&#8221; to which he replies &#8220;Rather!&#8221;, in stereotypical rich-guy fashion.</p>

<p>We had some spare time at the airport on Friday morning and I had this scenario that kept playing in my head and getting more intricate and so I wrote it down on a notepad I keep in my bag with the intention of posting it <em>somewhere</em> on the internet. Little did I know then that I would come up with the brilliant idea of posting it on my main blog. This isn&#8217;t my idea, but rather an inspired idea from the awesome conversation we had Thursday night. Thanks guys, you know who you are.</p>

<p>So without further ado, I introduce you to <em>The Richest Man Alive</em>:</p>
<hr />
<p>Markus, the cleaner for Lord Nelson&#8217;s third pool, has just been found floating dead in the pool he was supposed to be cleaning.</p>

<p>Lord Nelson sits in his favourite chair by the fire that his stereotypically named butler, Alfred, has beautifully crafted. The butler stands to the right of the chair, dressed immaculately as can be expected by butlers. They discuss the death of Markus.</p>

<p>&#8220;Sherry?&#8221;, Alfred asked.</p>

<p>&#8220;Rather.&#8221;, Lord Nelson replies with his thick British-monarch-but-not accent.</p>

<p>Alfred pours a glass of sherry and hands it to Lord Nelson, who then sips it.</p>

<p>&#8220;It&#8217;s quite atrocious, really.&#8221;, Lord Nelson says.</p>

<p>&#8220;The sherry?&#8221;, Alfred asks, like a dog who&#8217;s being told off by his owner. &#8220;My deepest&#8230;&#8221;</p>

<p>&#8220;No no, Alfred, about the third pool. The cleaning lad floating in it?&#8221;</p>

<p>&#8220;Quite, sir.&#8221;</p>

<p>&#8220;When did they find him?&#8221;</p>

<p>&#8220;Yesterday afternoon, while you were golfing on the eastern course, sir.&#8221;</p>

<p>&#8220;Tragic, really. We&#8217;ll never get the smell out.&#8221;</p>

<p>&#8220;I will endeavour, sir.&#8221;</p>

<p>&#8220;That would be grand, Alfred. Please do see to his arrangements I believe he was in the 4th bedroom on the 5th floor.&#8221;</p>

<p>&#8220;Yes sir, you are correct. I will attend to those right away, sir.&#8221;</p>

<p>&#8220;Where the devil do we find one as &#8230; talented as Markus?&#8221;</p>

<p>&#8220;I do not have a clue sir, although I suspect we may be able to find one and bring him in shortly.&#8221;</p>

<p>&#8220;I am awfully fond of that idea, Alfred, but do you not remember the fuss Markus put up for the first week?&#8221;</p>

<p>&#8220;Quite, sir. He complained quite emotionally about his treatment by Boris.&#8221;</p>

<p>&#8220;Yes, Alfred.&#8221;, Lord Nelson replies, sipping his expensive sherry.</p>

<p>&#8220;Being pulled off the street and pushed into a limousine would do do that though.&#8221;</p>

<p>&#8220;I agree, but only in part. Boris does need to learn &#8216;the soft touch&#8217;&#8221;</p>

<p>&#8220;Rather, sir. I remember my &#8230; abduction, fondly.&#8221;</p>

<p>&#8220;Money fills that void, Alfred.&#8221;</p>

<p>&#8220;Quite, sir. Quite. Margaret is exceptionally glad to receive your annual letters informing her of my continued survival and exceptional service.&#8221;</p>

<p>&#8220;Indeed.&#8221;</p>

<p>&#8220;How should I deal with this, sir?&#8221;</p>

<p>&#8220;Hmm?&#8221;</p>

<p>&#8220;The body, in the third pool?&#8221;</p>

<p>&#8220;Ahh, yes. Get Boris to remove it. I hear he has &#8230; experience with these matters.&#8221;</p>

<p>&#8220;KGB, sir.&#8221;</p>

<p>&#8220;Yes, yes. Good lad. Do find a replacement, Alfred.&#8221;</p>

<p>&#8220;For Boris?&#8221;, Alfred asks hopefully.</p>

<p>&#8220;No, not yet. Just the pool boy. God rest his soul.&#8221;</p>

<p>&#8220;Will that be all sir?&#8221;</p>

<p>&#8220;Yes, Alfred.&#8221;</p>

<p>&#8220;Thank you sir, I will deal with these matters right away.&#8221;</p>

<p>Alfred leaves the room, while Lord Nelson finishes his sherry.</p>]]></content>
 </entry>
 
 <entry>
   <title>Whodunit: Devise, OmniAuth, OAuth or GitHub?</title>
   <link href="http://ryanbigg.com/2011/04/whodunit-devise-omniauth-oauth-or-github" />
   <updated>2011-04-11T00:00:00+10:00</updated>
   <id>http://ryanbigg.com/2011/04/whodunit-devise-omniauth-oauth-or-github</id>
   <content type="html"><![CDATA[<p>(If it wasn&#8217;t obvious enough: my previous blog post about Rails 3.1 in Action is an April Fools joke. If Rails 3.1 is released before Rails 3 in Action goes to print, Rails 3 in Action will most likely contain the 3.1 updates necessary)</p>

<p>I&#8217;m currently writing what is the final chapter in Rails 3 in Action and I&#8217;m pretty excited about it. It&#8217;s the &#8220;Alternative Authentication&#8221; chapter, Chapter 14. It&#8217;s not to say there are 14 chapters in the book&#8230; there aren&#8217;t. There&#8217;s seventeen chapters two, maybe three appendicies. This happens to be the last chapter I have to work on and its number is 14.</p>

<p>When I begun writing the book back near the end of April last year I sketched out the idea of this chapter thinking it would be a good thing to show people because a lot of people seem to struggle (myself included) in setting up alternative means of authentication using OAuth (and OpenID, etc.) providers. I personally had no idea what I was going to do write in it at that point in time, but that&#8217;s how I&#8217;ve been writing the book thus far and it&#8217;s turned out pretty alright I hear.</p>

<p>Then a couple of months ago, <a href='http://github.com/intridea/omniauth'>OmniAuth</a> came onto the scene. My god, it was like Christmas came early. It claimed to simplify the authentication process of alternative services down to its most basic forms. I distinctly remembering trying it out almost immediately and staring in starry-eyed wonder at the process as it worked seamlessly with Twitter and GitHub. That was back in November and I had other chapters I was working on then, like Chapter 11.</p>

<p>With the final chapters of the book I&#8217;ve adopted a &#8220;work on whatever you feel like&#8221; stance with them, as they aren&#8217;t required to be done in any particular order. For example, I did the &#8220;Engines&#8221; chapter (16) before I did the chapter on &#8220;Basic performance enhancements&#8221; (15) and &#8220;Rack applications&#8221; (17). It just so happened that Chapter 14 got left to last.</p>

<p>So I worked on it beginning the middle of last week, implementing basic Twitter authentication and writing a pretty decent first draft of it over the next two days. Then on Friday I accidentally deleted my work for the chapter up to about the 20th line in the document (from somewhere around the 350 range) when I ran one of my publishing scripts over it. I had no backups, and it wasn&#8217;t version controlled. I felt like an idiot.</p>

<p>Over this past weekend I&#8217;ve re-written all of what I did with Twitter on the Friday night and Saturday (which was a poor day of writing, was too distractable). Sunday morning I revised the section and Sunday afternoon I begun in my attempt to use GitHub. That&#8217;s when things stopped flowing.</p>

<p>When I write the book I attempt things in the ticketee application first and then just copy over the working code samples from that into the book. It&#8217;s a little bit of a laborious process, but it&#8217;s worked so far (I know there&#8217;s better ways, I just don&#8217;t have the time to do them). When I attempted GitHub authentication using Devise 1.2.1&#8217;s OmniAuth (0.2.1) authentication support it told me &#8220;Invalid credentials&#8221;.</p>

<p>I was incredulous. How could I stuff up something so basic when it worked so well with Twitter? I spent the afternoon calling Devise nasty names both out loud and on Twitter and went to bed early, defeated. I could not for the life of me figure this out.</p>

<p>I awoke after a terrible night&#8217;s sleep (the kind you have when the problem is right there and you know the solution is there, but isn&#8217;t). I dreamed mostly of code. I awoke feeling strangely refreshed at 6am and did the usual morning things before attempting the problem again.</p>

<p>I made sure I had the absolute latest version of Devise and OmniAuth. I did.</p>

<p>I made sure I was able to create a new GitHub application and duplicate these conditions, both on Ticketee and on a brand new Rails application. I was able to do that too.</p>

<p>I was still utterly convinced it was something Devise was doing. I had pointed my finger squarely at it for the past 9 awake hours and why should I question my opinion then? I wanted to make extra sure, so I tried <em>another</em> brand new Rails 3 application but didn&#8217;t use Devise. I used straight OmniAuth (thanks to <a href='http://railscasts.com/episodes/241-simple-omniauth'>Ryan Bates' superb Railscast on it</a>) and it still didn&#8217;t work.</p>

<p>Blast! My prime suspect was no longer prime, nor a suspect! So it was something to do with OmniAuth then, perhaps. I found an application called <a href='http://github.com/markusproske/omniauth_pure'>`omniauth_pure`</a> which claimed to offer a basic example of OmniAuth authentication. I tried this and&#8230;</p>

<p>It worked! The damn thing worked. So what was different? Well, I noticed that they were using an older version of the oa-oauth gem (v0.2.0) where I was using v0.3.0. I suspected a problem had been generated between these two versions, and my finger was then pointed at OmniAuth as being the source of all my trouble.</p>

<p>I cloned <code>git://github.com/intridea/omniauth</code> into the <code>vendor/gems/omniauth</code> folder of my application, update the <code>Gemfile</code> accordingly, and tried it again and it was still broken. Ok, it still looked like an omniauth problem. So I did a <a href='https://gist.github.com/912916'>git bisect</a> (saviour!) and came up with a commit by none other than Michael Bleigh himself: <code>72b9b619bbc2a41b61ee4ec108bdfa4dc16838f9</code>.</p>

<p>Aha! This commit bumped the oauth2 dependency and, according to <code>git bisect</code>, that commit is to blame for my source of woe. But it&#8217;s not, because it&#8217;s innocently bumping a gem version up, it&#8217;s actually oauth2.</p>

<p>So my finger now switches for a second time to the oauth2 gem. I clone this into the <code>vendor/gems/oauth2</code> directory, update the <code>Gemfile</code> and do a git bisect on it. The <a href='https://gist.github.com/912926'>results</a> indicated a commit that I could blame for all my troubles.</p>
<a href='https://github.com/intridea/oauth2/commit/1dbfe18af997c45a69fdea29192f599f20d80879'>This commit.</a>
<p>It dutifully changes a small detail, the <code>@token\_param</code> to be the <a href='http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-5.1.2'>OAuth2 draft 10 specified (in section 5.1.2)</a> &#8220;oauth_token&#8221; rather than &#8220;access_token&#8221;. This means that all providers who have updated to this draft specification are now supported by the oauth2 gem but those who have not, <em>like GitHub</em>, are left behind.</p>

<p>Ladies and gentleman, after my long story, let me present to you Exhibit A, direct from <a href='http://develop.github.com/p/oauth.html'>GitHub's OAuth documentation</a>:</p>
<img src='https://img.skitch.com/20110411-qn2ps6uckm4deq851ubydjtf71.png' />
<p>A keen eye, keener than my own, would notice here that the parameter is not called &#8220;oauth_token&#8221; as is being supplied by the oauth2 gem now as of the afore-mentioned commit, but rather it&#8217;s still called &#8220;access_token&#8221;.</p>

<p>I submit to you that GitHub&#8217;s OAuth 2 specification is broken, but the <a href='http://support.github.com/discussions/site/3398-your-oauth-implementation-is-broken-but-heres-a-fix'>fix is extremely easy</a> and only GitHub (or a hack to oauth2) can fix it.</p>

<p>That was quite a lot of frustration caused by that one small little detail. This was very fun to track down and the high I got from solving it was well worth it. It&#8217;s one of the things I enjoy most as a programmer is solving a difficult bug.</p>
<strong>Update:</strong>
<p>The problem itself won&#8217;t be fixed until the OAuth2 specification solidifies or <code>oauth2</code> hacks around it to support different services calling this parameter by different names.</p>]]></content>
 </entry>
 
 <entry>
   <title>Rails 3.1 in Action</title>
   <link href="http://ryanbigg.com/2011/04/rails-3-1-in-action" />
   <updated>2011-04-01T00:00:00+11:00</updated>
   <id>http://ryanbigg.com/2011/04/rails-3-1-in-action</id>
   <content type="html"><![CDATA[<h1>THIS WAS MY APRIL FOOLS JOKE FOR 2011. DO NOT TAKE THIS SERIOUSLY.</h1>
<p>I&#8217;m edging ever closer to finishing Rails 3 in Action with only 3 and a half chapters remaining (_Translations_, <em>Background Jobs</em>, <em>Alternative Authentication</em> and <em>Mounting Rack Applications</em> being the half). I&#8217;m hoping to knock them off on the next couple of weeks and then the book will be (besides the appendicies) content complete! Finally.</p>

<p>So I think now is a good time to announce my next book: tentatively called <em>Rails 3.1 in Action</em>. This book will contain the same content as Rails 3 in Action but will be specifically directed at people who are running Rails 3.1 rather than Rails 3.0 and so some of the content will be modified to accommodate these changes. The main changes of this will be the moving of the <em>Engines</em> and <em>Mounting Rack Applications</em> chapters from <em>Rails 3 in Action</em> into <em>Rails 3.1 in Action</em>, basically because Rails 3.0 doesn&#8217;t have the necessary features to accommodate the awesome things these chapters do, where Rails 3.1 does. Another change is the updating of Chapter 8 from using Prototype (eeew) to jQuery (yaaaay). If you have bought copies of these chapters for <em>Rails 3 in Action</em> we ask kindly that you return them (the chapters, you can keep the rest of the book) and wait until <em>Rails 3.1 in Action</em> comes out with the updated copies.</p>

<p>Manning, Yehuda, our reviewers and I have been talking about the best way to accommodate the readers who have 3.0 applications as well as 3.1 applications (soon enough, this will be the case) and we have decided the best way is to split it out into another book. Rather than have a <em>2nd edition</em> released so close to the first edition, we&#8217;re going to give this book another name to clearly differentiate it between the original (and quite clearly, the best) Rails 3 book.</p>

<p>The day that Rails 3.1 is released is the same day you can expect to be able to visit your nearest bookshop and purchase this new installment of the <em>Rails X in Action</em> series.</p>

<p>Thanks for your support, purchases, comments and praise so far. It really helps!</p>]]></content>
 </entry>
 
 
</feed>

