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

<channel>
	<title>Sarah Mei</title>
	<atom:link href="http://www.sarahmei.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sarahmei.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 25 Jul 2010 23:48:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Safe Facebooking</title>
		<link>http://www.sarahmei.com/blog/2010/07/25/safe-facebooking/</link>
		<comments>http://www.sarahmei.com/blog/2010/07/25/safe-facebooking/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 23:48:21 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[paranoia]]></category>
		<category><![CDATA[rants]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=554</guid>
		<description><![CDATA[I have a Facebook account on which I have duly locked down the privacy controls (several times, it feels like). In theory, no one can get at my information unless we become Facebook friends.
In practice, I&#8217;ve discovered, it&#8217;s another story entirely. After spending the better part of ten days, recently, integrating Facebook into another website, [...]]]></description>
			<content:encoded><![CDATA[<p>I have a Facebook account on which I have duly locked down the privacy controls (several times, it feels like). In theory, no one can get at my information unless we become Facebook friends.</p>
<p>In practice, I&#8217;ve discovered, it&#8217;s another story entirely. After spending the better part of ten days, recently, integrating Facebook into another website, I have new rules for how I use Facebook. I realize they sound a little tin-foil-hat-style crazy, so after the rules I&#8217;ll explain a bit about why I adopted them.<br />
<span id="more-554"></span></p>
<div id="attachment_561" class="wp-caption alignright" style="width: 268px"><a href="http://www.flickr.com/photos/8188326@N02/3248980358/" target="_blank"><img class="size-full wp-image-561" title="tin-foil-hat" src="http://www.sarahmei.com/blog/wp-content/uploads/2010/07/3248980358_3cc305c96a_o.jpg" alt="Image by CycleDog" width="258" height="300" /></a><p class="wp-caption-text">Image by CycleDog</p></div>
<p><strong>Rule 0: I&#8217;m not closing my Facebook account.</strong> I know a few people who have gotten off Facebook entirely, recently, but Facebook is the only place I&#8217;m in touch with my cousins who live out of state, my best friends from elementary school who are scattered to the wind, and my husband&#8217;s family who live on the east coast. These people aren&#8217;t going to get on Twitter, and I do want to hear about their lives.</p>
<p><strong>Rule 1: I always browse Facebook in a separate browser.</strong> If I&#8217;m doing my random web browsing in Firefox, then I open Facebook in Chrome (or less frequently, Safari). It&#8217;s not sufficient to open Facebook in a different window of the same browser, or a different tab of the same browser. It has to be a <em>different</em> browser. (If you only have one browser right now, you can <a href="http://www.mozilla.com/en-US/firefox/firefox.html" target="_blank">install Firefox here</a>, or <a href="http://www.google.com/chrome" target="_blank">Chrome over here</a>.)</p>
<p><strong>Rule 2: I make sure my non-Facebook browser has no residual FB cookies.</strong> I used to just leave a Facebook tab open while I browsed random web sites in other tabs, but that&#8217;s incredibly dangerous. If I am logged in to FB, any of those third-party sites could be silently collecting my Facebook information without notifying me. Once I decided to separate my browsing, I deleted all cookies in my non-Facebook browser. As long as I don&#8217;t log in to FB again in that browser, other sites won&#8217;t be able to access my Facebook information.</p>
<p><strong>Rule 3: I never browse anywhere else in the Facebook browser.</strong> I use Chrome for Facebook, so I don&#8217;t use Chrome for anything else. Any external links I want to click on from Facebook, I open in Firefox. This can be a pain in the ass because links on FB usually redirect you through another FB page. So in FB, I right click the link, select &#8220;Copy link location&#8221;, switch to Firefox, paste the link in, edit it to remove the Facebook prefix, and then hit return to go there.</p>
<p>In practice, I do use Chrome for other stuff, but I log out of Facebook and clear all my cookies first. Which leads to&#8230;</p>
<p><strong>Rule 4: I always log out of Facebook.</strong> They&#8217;ve hidden the log out option; it&#8217;s at the top right, the last option under &#8220;Account.&#8221; It&#8217;s not sufficient to close the Facebook window, or even to quit the browser you&#8217;re using for Facebook. In either case you leave behind a set of &#8220;logged in&#8221; FB cookies that other sites can read. I always explicitly log out of FB when I&#8217;m done.</p>
<p><strong>Rule 5:</strong> There is no rule 5.</p>
<p><strong>Rule 6: I never use Facebook to log in to another web site.</strong> Any web site can use Facebook as their log in system, instead of (or in addition to) letting visitors create accounts. Most of these sites are not officially affiliated with Facebook. It&#8217;s convenient to use FB for this, sometimes, instead of creating yet another username and password to remember.</p>
<p>But it&#8217;s also dangerous. When I authorize a site to use Facebook to log me in, that site can then access my name, my email address, all the schools I went to, all my employers past and present, my interests and hobbies, my pictures, my wall, my messages, and my friends. Among other things. And the site may hold on to that data, so even if I change it or hide it in Facebook, it&#8217;ll be in their database in perpetuity. Since the site isn&#8217;t affiliated with Facebook, it&#8217;s not bound by their privacy policy, so who knows what it will do with the information? It&#8217;s way better to just set up another account with a throw-away username and password.</p>
<h2>Feeling crazy yet?</h2>
<p>I am. Or maybe &#8220;paranoid&#8221; is a better word. Before I started working with the Facebook API, I had no idea how much information was available to third-party web sites. Things I don&#8217;t think of as public &#8211; including my email address &#8211; are available by default. </p>
<p>There are, of course, terms of service that those sites have agreed to, but nobody checks or audits them. It&#8217;s trivially easy to sign up for a developer account, create a Facebook application, stick some Javascript on a site, and start collecting the data of unwary FB members who visit you. </p>
<h2>The public/private dilemma</h2>
<p>Honestly, most of the information I have on Facebook is public knowledge anyway, including my email address. But it doesn&#8217;t sit well with me that FB lets third-party sites access information that non-friends can&#8217;t see. What else might they decide to share someday &#8211; the links I&#8217;ve clicked on? The groups I&#8217;ve visited but not joined? The exes I&#8217;ve searched for?</p>
<p>By keeping Facebook quarantined, I hope to contain the fallout of any future &#8220;experience enhancements.&#8221; </p>
<p>And now, if you&#8217;ll excuse me, I need to go use my hat to make dinner.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/07/25/safe-facebooking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RailsConf Slides &#8211; Beyond (No)SQL</title>
		<link>http://www.sarahmei.com/blog/2010/06/09/railsconf-slides/</link>
		<comments>http://www.sarahmei.com/blog/2010/06/09/railsconf-slides/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 16:26:54 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsconf]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=544</guid>
		<description><![CDATA[Preliminary slides for my RailsConf talk I&#8217;m giving this afternoon on conceptual tools for evaluating databases. Contains some profanity at the beginning. Slides are subject to change since I haven&#8217;t actually given the talk yet!

Beyond (No)SQL
View more presentations from Sarah Mei.

]]></description>
			<content:encoded><![CDATA[<p>Preliminary slides for my RailsConf talk I&#8217;m giving this afternoon on conceptual tools for evaluating databases. <strong>Contains some profanity at the beginning.</strong> Slides are subject to change since I haven&#8217;t actually given the talk yet!<br />
<span id="more-544"></span></p>
<div style="width:425px" id="__ss_4453924"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/sarahmei/beyond-nosql" title="Beyond (No)SQL">Beyond (No)SQL</a></strong><object id="__sse4453924" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=beyond-no-sql-100609112040-phpapp02&#038;stripped_title=beyond-nosql" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4453924" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=beyond-no-sql-100609112040-phpapp02&#038;stripped_title=beyond-nosql" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/sarahmei">Sarah Mei</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/06/09/railsconf-slides/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Outside-In BDD: How?!</title>
		<link>http://www.sarahmei.com/blog/2010/05/29/outside-in-bdd/</link>
		<comments>http://www.sarahmei.com/blog/2010/05/29/outside-in-bdd/#comments</comments>
		<pubDate>Sun, 30 May 2010 03:14:55 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=443</guid>
		<description><![CDATA[I use rspec on every project, and I&#8217;ve started adding cucumber to all my projects in the last few months. There&#8217;s lots of information out there about how to set up and use cucumber, but there isn&#8217;t much covering your developer workflow when you&#8217;re using these tools.
How do you start, and how do you know [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://rspec.info/">rspec</a> on every project, and I&#8217;ve started adding <a href="http://cukes.info">cucumber</a> to all my projects in the last few months. There&#8217;s lots of information out there about how to set up and use cucumber, but there isn&#8217;t much covering your developer workflow when you&#8217;re using these tools.</p>
<p>How do you start, and how do you know you&#8217;re finished? What do you test, and where? These questions can be answered hundreds of different ways, but here&#8217;s my way.<br />
<span id="more-443"></span></p>
<h2>The first code I write: a feature</h2>
<p>As a developer, rather than a designer, I&#8217;m always tempted to start with unit tests and work out towards a cucumber feature (&#8220;inside-out&#8221; testing). But that approach gets me into no end of trouble. I usually end up writing and testing stuff on the model that I don&#8217;t ultimately need. Plus once I&#8217;m down in the weeds coding, I lose track of the big picture.</p>
<p>So I like to do outside-in testing instead. I start each story I get from <a href="http://pivotaltracker.com">tracker</a> with a cucumber feature that expresses how the PM will be able to accept it when I&#8217;m done. The feature helps me frame the problem properly, and focus on doing exactly what I need to make it work. Since I come back to it periodically while I&#8217;m coding, I keep focused on the higher-level goal. And finally &#8211; if I write it first, I can&#8217;t skip writing it once I&#8217;m done.</p>
<h2>Before we get going&#8230;</h2>
<p>There are certain types of tests I don&#8217;t write in this example (and in some cases, at all). Let&#8217;s get those out of the way so you don&#8217;t have to come up with a scathing comment at the bottom of the post.</p>
<ul>
<li><strong>Model tests.</strong> In this example, my model doesn&#8217;t do anything other than default ActiveRecord behavior, so it doesn&#8217;t need any tests. <strong>Don&#8217;t test rails internals.</strong> Once my model has custom behavior, it will have specs, too.</li>
<li><strong>View tests.</strong> I have no tests that verify that my markup is what I expect. That&#8217;s because they&#8217;re a waste of time. Yes, even with complex views. Verify behavior with cucumber tests, unit-test Javascript with <a href="http://github.com/pivotal/jasmine">jasmine</a>, and leave the rest to the humans. You&#8217;ll waste more developer time maintaining them than it would take humans to verify them. Verifiers are a whole lot cheaper than developers.</li>
<li><strong>Error case tests.</strong> In this example, there are no error cases. The model has no validations, and the table has no constraints. Once there are error cases, I generally put those in the model if I can, in the controller when I have to, and never in the cucumber tests. The latter is mostly a suite-speed consideration &#8211; cucumber tests run much more slowly than rspec. Cucumber&#8217;s great for for happy path tests; I leave the rest to rspec.</li>
</ul>
<p>Let&#8217;s get going!</p>
<h2>The first feature</h2>
<p>Say I&#8217;m doing a library app and the first story is &#8220;User can enter a new book into the system.&#8221; Before I write any other code, I write this feature:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Feature: User manages books
  Scenario: User adds a new book
    Given I go to the new book page
    <span style="color:#9966CC; font-weight:bold;">And</span> I fill <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#996600;">&quot;Name&quot;</span> with <span style="color:#996600;">&quot;War &amp; Peace&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">And</span> I fill <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#996600;">&quot;Description&quot;</span> with <span style="color:#996600;">&quot;Long Russian novel&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">When</span> I press <span style="color:#996600;">&quot;Create&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">Then</span> I should be on the book list page
    <span style="color:#9966CC; font-weight:bold;">And</span> I should see <span style="color:#996600;">&quot;War &amp; Peace&quot;</span></pre></div></div>

<h2>Starting the fail-fix cycle</h2>
<p>I run it using <code>cucumber features</code>, and it fails on the first line &#8211; <code>Given I go to the new book page</code> &#8211; because cucumber doesn&#8217;t know where the &#8220;new book page&#8221; is. So I add that to the cucumber paths helper.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>the new book page<span style="color:#006600; font-weight:bold;">/</span>
      new_book_path</pre></div></div>

<p>Now when I run cucumber, it fails because it can&#8217;t find <code>new_book_path</code>. So I add that to <code>routes.rb</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:books</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:new</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Now when I run cucumber, it complains that it can&#8217;t find the BooksController. That means it&#8217;s time to dive down to rspec controller tests. </p>
<h2>My first spec experience</h2>
<p>I create <code>books_controller_spec.rb</code> in spec/controllers, and add a test for the <code>new</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#996600;">'..'</span>, <span style="color:#996600;">'spec_helper.rb'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
describe BooksController <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;#new&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;should be successful&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      get <span style="color:#ff3333; font-weight:bold;">:new</span>
      response.<span style="color:#9900CC;">should</span> be_success
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>When I run this spec, it complains that there is no BooksController. Fixed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> BooksController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController 
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p></code><br />
I re-run the spec and get "no action responded to new." So I add the <code>new</code> method.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> BooksController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> new
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the spec passes! Time to check back with cucumber.</p>
<h2>Getting past the first line</h2>
<p>I read through my cucumber feature again:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Feature: User manages books
  Scenario: User adds a new book
    Given I go to the new book page
    <span style="color:#9966CC; font-weight:bold;">And</span> I fill <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#996600;">&quot;Name&quot;</span> with <span style="color:#996600;">&quot;War &amp; Peace&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">And</span> I fill <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#996600;">&quot;Description&quot;</span> with <span style="color:#996600;">&quot;Long Russian novel&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">When</span> I press <span style="color:#996600;">&quot;Create&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">Then</span> I should be on the book list page
    <span style="color:#9966CC; font-weight:bold;">And</span> I should see <span style="color:#996600;">&quot;War &amp; Peace&quot;</span></pre></div></div>

<p>Last time I ran it, it failed on the first line because it couldn't find the BooksController. This time, same location, but it says it can't find the view. So whiny! To placate it, I create an empty view called <code>new.html.erb</code> and run it again.</p>
<p>Now cucumber gets past line 1 (huzzah!!) and fails on line 2 (<code>And I fill in "Name" with "War &amp; Peace"</code>) with the message that it can't find a field called Name to fill in. So I add a standard rails form to the view.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%-</span> form_for <span style="color:#0066ff; font-weight:bold;">@book</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">label</span> <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">text_area</span> <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">&quot;Create&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%-</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>Uh oh. Cucumber is mad at me because there is no <code>@book</code> object. Back to rspec for me!</p>
<h2>rspec: The Return</h2>
<p>In my controller's <code>new</code> method, I need to create a book object that the form will use. I first add a test for that in the controller spec:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#996600;">'..'</span>, <span style="color:#996600;">'spec_helper.rb'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
describe BooksController <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;#new&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    before <span style="color:#9966CC; font-weight:bold;">do</span>
      get <span style="color:#ff3333; font-weight:bold;">:new</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    it <span style="color:#996600;">&quot;should be successful&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      response.<span style="color:#9900CC;">should</span> be_success
    <span style="color:#9966CC; font-weight:bold;">end</span>
    it <span style="color:#996600;">&quot;should create a book object&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:book</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should_not</span> be_nil
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This fails the right way - it says assigns(:book) is nil. So then I add the creation of the book object to the controller.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> BooksController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    <span style="color:#0066ff; font-weight:bold;">@book</span> = Book.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the spec fails, saying it can't find the Book class. It has a point - I haven't created the model yet. Fixed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Book <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now it fails saying it can't find the books table. So I write a migration that creates that.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> CreateBooksTable <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migration</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    create_table <span style="color:#ff3333; font-weight:bold;">:books</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
      t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:name</span>
      t.<span style="color:#9900CC;">text</span> <span style="color:#ff3333; font-weight:bold;">:description</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">down</span>
    drop_table <span style="color:#ff3333; font-weight:bold;">:books</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Once I do <code>rake db:migrate</code> and <code>rake db:test:prepare</code>, I re-run my controller spec....and it passes! Back to the cucumber feature!</p>
<h2>Cucumber...again.</h2>
<p>In our last episode, cucumber was visibly annoyed because there was no <code>@book</code> object for the form to operate on. I run it again to see if it's still sulking.</p>
<p>Yep. This time it tells me that it can't find books_path. <code>form_for</code> tries to submit to the create path by default, which I haven't added yet. I add it to the routes.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:books</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:new</span>, <span style="color:#ff3333; font-weight:bold;">:create</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>This time, when I run cucumber, it gets through the first three lines (woo hoo!) and fails on the 4th, saying no action responded to create. Back to the rspec-cave, batman!</p>
<h2>rspec: The Sequel to The Return</h2>
<p>I add a controller spec for the <code>create</code> method.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  describe <span style="color:#996600;">&quot;#create&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;should create a new book&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      post <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#996600;">&quot;book&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;name&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Jane Eyre&quot;</span>, <span style="color:#996600;">&quot;description&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Something Victorian&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:book</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should_not</span> be_nil
      assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:book</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">name</span>.<span style="color:#9900CC;">should</span> == <span style="color:#996600;">&quot;Jane Eyre&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>When I run it, I get the same message as in cucumber: no action responded to create. So I create the create:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> BooksController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    <span style="color:#0066ff; font-weight:bold;">@book</span> = Book.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> create
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now when I re-run the spec, it fails saying that assigns(:book) is nil, which makes sense. I put in the guts of <code>create</code> to make that pass.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@book</span> = Book.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:book</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@book</span>.<span style="color:#9900CC;">save</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now rspec passes! Back to cucumber. </p>
<h2>So...cucumber. We meet again.</h2>
<p>When I re-run the feature, it says I'm missing a template for create, which is correct. However, in this case, I don't want to make a template for create - I want to redirect to the book list page. So once again, I'm back with rspec.</p>
<h2>rspec: Back so soon?</h2>
<p>I add that expectation to the controller spec for <code>create</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    it <span style="color:#996600;">&quot;should redirect to the book list page&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      response.<span style="color:#9900CC;">should</span> redirect_to books_path
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>It fails saying there's no redirect. So to make it pass, I add a redirect to the controller code.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@book</span> = Book.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:book</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@book</span>.<span style="color:#9900CC;">save</span>
      redirect_to books_path
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now my controller specs pass. Cucumber, I'm coming for you!</p>
<h2>Oh, you again.</h2>
<p>Last time, we got through the first 3 lines of the feature and failed on line 4 (<code>When I press "Create"</code>). When I run it this time, it gets through the same 3 lines and then fails in the same place again, saying that no action responded to index. I add <code>index</code> to the routes.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:books</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:new</span>, <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:index</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>I re-run the feature and get the same error message. WTF, cucumber?! It turns out that rails' implementation of REST uses the same path helper for create and index, so the path helper for <code>index</code> already exists, even though the method does not. A little strange, I know. But we need an <code>index</code> method, so it's back to rspec.</p>
<h2>rspec: For the first time, for the last time...</h2>
<p>I write a spec for the <code>index</code> method.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  describe <span style="color:#996600;">&quot;#index&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;should be successful&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      get <span style="color:#ff3333; font-weight:bold;">:index</span>
      response.<span style="color:#9900CC;">should</span> be_success
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I still get no action responded to index. So l add the method in BooksController, empty to start.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> index
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Specs pass, back to cucumber!</p>
<h2>How can I miss you if you won't go away?</h2>
<p>Cucumber tells me there's no template for index. So I create an empty one, and re-run. This run, for the first time, I pass line 4 (yaaaaay) but then it fails on line 5 (<code>Then I should be on the book list page</code>) because it can't figure out what I mean by "the book list page." That goes in the cucumber path helper.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>the book list page<span style="color:#006600; font-weight:bold;">/</span>
      books_path</pre></div></div>

<p>OMG five out of six steps pass! Now cucumber says it can't find "War &amp; Peace" on the page, so let's make the index view list the existing books. Back to rspec...</p>
<h2>Don't go away mad...just go away.</h2>
<p>I add the following <code>it</code> block to the spec for <code>index</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    it <span style="color:#996600;">&quot;should assign a list of existing books&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      Book.<span style="color:#9900CC;">create</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Endymion&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;weird&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      get <span style="color:#ff3333; font-weight:bold;">:index</span>
      assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:books</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should_not</span> be_nil
      assigns<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:books</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">length</span>.<span style="color:#9900CC;">should</span> == <span style="color:#006666;">1</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>It fails because I'm not creating @books in the controller, so I fix that.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> index
    <span style="color:#0066ff; font-weight:bold;">@books</span> = Book.<span style="color:#9900CC;">all</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the specs pass - back to cucumber. </p>
<h2>We really have to stop seeing each other like this.</h2>
<p>Cucumber still says it can't find War &amp; Peace, because I haven't added printing out the books to the index view. I'll fix that.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%-</span> <span style="color:#0066ff; font-weight:bold;">@books</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>book<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
    &lt;strong&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= h book.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/strong&gt;
    <span style="color:#006600; font-weight:bold;">&lt;%</span>= h book.<span style="color:#9900CC;">description</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%-</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>Re-run cucumber and ... ta-da! The feature passes! I've done everything I need to call the story done. I have the minimum amount of code I need, because all the code I wrote was driven by the feature. Story: <strong>delivered</strong>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/05/29/outside-in-bdd/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Another Ruby hack night!</title>
		<link>http://www.sarahmei.com/blog/2010/05/22/ruby-hack-night-61/</link>
		<comments>http://www.sarahmei.com/blog/2010/05/22/ruby-hack-night-61/#comments</comments>
		<pubDate>Sat, 22 May 2010 22:02:43 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[pivotal]]></category>
		<category><![CDATA[sfruby]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=436</guid>
		<description><![CDATA[I&#8217;ll be hosting another Ruby hack night on Tuesday, June 1st, at Pivotal Labs &#8211; 731 Market St, between 3rd and 4th in San Francisco. You can RSVP here.
You&#8217;re welcome to bring any sort of Ruby-related project! The theme for the evening is Javascript testing, following on this month&#8217;s monthly meetup. But I won&#8217;t make [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be hosting another Ruby hack night on Tuesday, June 1st, at Pivotal Labs &#8211; 731 Market St, between 3rd and 4th in San Francisco. You can RSVP <a href="http://www.meetup.com/sfruby/calendar/13534634/">here</a>.</p>
<p>You&#8217;re welcome to bring any sort of Ruby-related project! The theme for the evening is Javascript testing, following on <a href="http://www.meetup.com/sfruby/calendar/13060368/">this month&#8217;s monthly meetup</a>. But I won&#8217;t make you write any Javascript if you don&#8217;t want to.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/05/22/ruby-hack-night-61/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby hack night</title>
		<link>http://www.sarahmei.com/blog/2010/04/21/ruby-hack-night/</link>
		<comments>http://www.sarahmei.com/blog/2010/04/21/ruby-hack-night/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 03:09:26 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[pivotal]]></category>
		<category><![CDATA[sfruby]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=420</guid>
		<description><![CDATA[
The peninsula has all kinds of neat hack events like SuperHappyDevHouse and various Hacker Dojo events. But I hate driving all the way down there just to hang out with hackers and get something done on a project. There are plenty of hackers in San Francisco. There might even be more of the type of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://maps.google.com/maps?f=q&#038;source=s_q&#038;hl=en&#038;geocode=&#038;q=731+Market+Street,+San+Francisco,+CA&#038;sll=37.781689,-122.391061&#038;sspn=0.009158,0.019205&#038;ie=UTF8&#038;hq=&#038;hnear=731+Market+St,+San+Francisco,+California+94103&#038;ll=37.786877,-122.404368&#038;spn=0.009157,0.019205&#038;z=16"><img src="/blog/wp-content/uploads/2010/04/731_market_st.jpg" alt="Pivotal Labs, 731 Market St, 3rd Floor" title="731_market_st" width="424" height="349" class="alignright size-full wp-image-537" /></a></p>
<p>The peninsula has all kinds of neat hack events like <a href="http://superhappydevhouse.org">SuperHappyDevHouse</a> and various <a href="http://hackerdojo.org">Hacker Dojo</a> events. But I hate driving all the way down there just to hang out with hackers and get something done on a project. There are plenty of hackers in San Francisco. There might even be <strong>more</strong> of the type of hackers I want to hang out with.</p>
<p>So I&#8217;ve decided to host a monthly hack night, to be held on the Tuesday following the monthly SF Ruby meetup. My employer, <a href="http://pivotallabs.com">Pivotal Labs</a>, has graciously volunteered their space. Since tonight is the SF Ruby meetup, the next hack night is <strong>next Tuesday</strong>, April 27th, from 7-9:30 (ish).</p>
<p><a href="http://bit.ly/dx3t9T">RSVP now!</a> See you next Tuesday.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/04/21/ruby-hack-night/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why I Don&#8217;t Work At Google</title>
		<link>http://www.sarahmei.com/blog/2010/04/17/why-i-dont-work-at-google/</link>
		<comments>http://www.sarahmei.com/blog/2010/04/17/why-i-dont-work-at-google/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 03:50:01 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[rants]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=371</guid>
		<description><![CDATA[I have a few friends who periodically ask me, "Why don't you work at Google?" To non-developers, Google seems like a programmer's paradise - smart people, free food, scooters! and interesting projects to work on. Google does indeed have all of these things.

It's not enough.]]></description>
			<content:encoded><![CDATA[<p>I have a few friends who periodically ask me, &#8220;Why don&#8217;t you work at Google?&#8221; To non-developers, Google seems like a programmer&#8217;s paradise &#8211; smart people, free food, scooters! and interesting projects to work on. Google does indeed have all of these things.</p>
<p>It&#8217;s not enough.</p>
<p><span id="more-371"></span></p>
<h2>On Being Smart</h2>
<p>Google likes to hire engineers based on how smart they are. Their interviews are full of interesting algorithmic questions and puzzles. If you&#8217;re into that stuff, it&#8217;s actually kind of fun. They and Microsoft in particular are famous for interviewing this way, but smaller companies do it too. I get several recruiter emails each week for startups where I could work with &#8220;a really smart team!!! engineers with ivy league degrees!!!&#8221;</p>
<p>I&#8217;ve always been &#8220;smart&#8221; (instead of athletic or popular), and I grew up reassured by adults that in their world, &#8220;smart&#8221; was the crucial component of success. Imagine my shock when I discovered that it was not, in fact, sufficient.</p>
<p>It isn&#8217;t sufficient for software development, either.</p>
<h3>What&#8217;s Missing Here?</h3>
<p>My first job out of college was at Microsoft. The people I worked with were, individually, very, very bright. As a team, though, we could never get traction. The effect was subtle. At the time, it felt like we were making progress. We had a lot of really detailed discussions about different implementation options, and everyone had interesting input. We wrote a good bit of code.</p>
<p>But we never actually finished anything, and eventually, it turned incredibly frustrating. I had been programming for maybe four years total at that point, and never at a real company before, but I already knew I hated writing software no one used.</p>
<p>For a long time after I left that team, I couldn&#8217;t put my finger on what went wrong. Clearly, we were all smart. Somehow as a group, though, we were dumb.</p>
<h3>&#8220;Gets Shit Done&#8221;</h3>
<p>There were a lot of factors in my frustrating experience &#8211; Microsoft&#8217;s waterfall process, the ongoing antitrust litigation, and political machinations around the project, just for starters. But I think the same group of engineers in a perfect modern environment would still flounder. There were too many people on the team who, individually, couldn&#8217;t finish anything. There was always a good reason why &#8211; some new requirement that necessitated a rewrite, or some piece that turned out to be more complex than anyone thought.</p>
<p>As a junior member of the team, I took these explanations at face value. With the benefit of ten more years of experience, though, I know that while it&#8217;s important to write quality software, it&#8217;s equally important to just fucking finish it.</p>
<p>There are a lot of smart engineers who understand this, and, sadly, a lot of smart engineers who don&#8217;t. Microsoft&#8217;s hiring process didn&#8217;t distinguish, and neither does Google&#8217;s. If I were to take a job there, I might be on a team where everyone is smart <strong>and</strong> can get shit done. There are certainly plenty of those at Google, as their products attest. But I might be on my Microsoft team again, only this time with free food and scooters.</p>
<p>That&#8217;s about as appealing as another winter in Redmond.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/04/17/why-i-dont-work-at-google/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Thoughts on two months of pairing</title>
		<link>http://www.sarahmei.com/blog/2010/04/14/thoughts-on-two-months-of-pairing/</link>
		<comments>http://www.sarahmei.com/blog/2010/04/14/thoughts-on-two-months-of-pairing/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 05:58:55 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[pairprogramming]]></category>
		<category><![CDATA[pivotal]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=343</guid>
		<description><![CDATA[Previous to joining Pivotal Labs, I didn&#8217;t do a whole lot of pair programming.
Hoo boy.
It&#8217;s been a little over two months since I started, and the number of hours I&#8217;ve spent solo programming since then would all fit in one workday. I&#8217;ve had some surprising realizations &#8211; about myself, my style, and my abilities &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Previous to joining Pivotal Labs, I didn&#8217;t do a whole lot of pair programming.</p>
<p>Hoo boy.</p>
<p>It&#8217;s been a little over two months since I started, and the number of hours I&#8217;ve spent solo programming since then would all fit in one workday. I&#8217;ve had some surprising realizations &#8211; about myself, my style, and my abilities &#8211; and more than a few DUH moments. This post is more a collection of anecdotes than a coherent essay, but if you&#8217;ve wondered what full-time pairing is like, I hope it gives you a few insights.</p>
<p>It does contain some profanity. I blame my co-workers for that.</p>
<p><span id="more-343"></span></p>
<h2>On Constraints</h2>
<p>Pivotal works a strict 8-hour day, in keeping with the agile principle of sustainable pace. But because all projects are paired (you cannot buy the services of a single Pivot &#8211; we only come in pairs) everyone has to be in the office at the same times every day. So everyone arrives at 9, everyone takes lunch from 12:30-1:30, and by 6:15 the office is a ghost town.</p>
<p>I knew I&#8217;d love the work &#8211; and I do &#8211; but I thought I&#8217;d be fighting the schedule. Nine to six would have been fantastic 10 years ago, but now that I have a husband and two kids&#8230;not so much. There isn&#8217;t a daycare in the city that stays open past 6, and it&#8217;s much harder for me to go to doctor appointments, school events, and all the other kidly activities that are, without fail, held between 9 and 6.</p>
<h2>The Punchline</h2>
<p>Now that I&#8217;m doing it, I <strong>love</strong> the fixed schedule. At other jobs, around 4pm every day, I&#8217;d start wondering about when I needed to leave. I&#8217;d try to remember who I was picking up, and when, and then I&#8217;d look it up on my calendar, and then I&#8217;d text Peter and ask whether there was anything I needed to ask or tell the daycare folks, and then I&#8217;d stress about getting enough work done before I had to take off.</p>
<p>There&#8217;s none of that anymore. I know exactly when I&#8217;m leaving, and since my pair is leaving at the same time there&#8217;s no pressure to stay longer to finish something off. When I&#8217;m working, I can be completely present. When I&#8217;m done, I don&#8217;t have to drag a laptop home and check email or fix the build once I get there. I don&#8217;t even know how to get into Pivotal&#8217;s VPN from home. I walk out of the building at 6:05 with a clear mind and a clear schedule for the rest of the night.</p>
<p>It&#8217;s fucking exhilarating.</p>
<h2>On Getting Shit Done</h2>
<p>Fundamentally, what I love about software development is writing code that people actually use. I love to finish things. So anything that makes me feel like I&#8217;m really GSD makes me incredibly happy.</p>
<p>When people talk about pairing, you hear a lot about how it &#8220;amplifies&#8221; their productivity. I am going to go on record with the truth, however. Pairing does not amplify my productivity. Instead, it erases all the bad habits I have that keep me from being a superstar on my own.</p>
<p>When I&#8217;m pairing, I can really get shit done.</p>
<p>By myself, I have a lot of roadblocks:</p>
<p><strong>Rabbit Holes. </strong>When trying to figure out some thorny bug by myself, I often follow the wrong line of inquiry too far. I follow it sometimes for the sake of completeness &#8211; of knowing with 100% certainty that some factor is <strong>not</strong> what&#8217;s causing the problem &#8211; when 90% or even 50% certainty would do. Something in my brain craves completeness, occasionally to the detriment of productivity, and particularly when I am tired (hello, parenthood). I usually don&#8217;t notice it when it&#8217;s happening. However, if I have to explain to someone else what I am doing, the ridiculousness of it all suddenly becomes obvious and I&#8217;m able to break out.</p>
<p><strong>Distractions.</strong> If I&#8217;m working by myself, I&#8217;m on email, I&#8217;m on IM, I&#8217;m on twitter, oh my tests are running so I&#8217;ll check hacker news&#8230;and on and on. That time adds up over the day. And of course once I look at my email I&#8217;ve switched contexts so going back to my code is another context switch, and even though it may only take a few minutes, that also adds up. It feels <strong>amazing</strong> to work solidly for four hours at a time on a problem. But somehow when it&#8217;s just me, I can&#8217;t always keep that focus. I think it&#8217;s the addition of the social input and output that lets my frontal cortex actually attend to the problem at hand, without going ooh-shiny all the time.</p>
<p>That, and the guilt trip from my pair when I do wander.</p>
<p><strong>Cheats.</strong> If someone&#8217;s watching, I don&#8217;t take shortcuts. I write the tests first. I refactor code that needs it. I focus on doing the simplest thing that could possibly work, without being sloppy. I make sure I understand what I&#8217;m doing before I do it. I&#8217;d like to say that I always do these things when on my own&#8230;I really would. But the truth is that sometimes I put logic in my view code, because christ, if I move that then I need to put it in a helper and make a new file and add a new spec, and I said I&#8217;d be done by the end of the day and it&#8217;s 4:30 and no one&#8217;s reviewing my code so&#8230;I just do it.</p>
<p>But if someone else is watching what I&#8217;m doing&#8230;I just don&#8217;t. That feels incredible.</p>
<p><strong>Too-Clever Syndrome. </strong>On the other side, I get excited by knotty technical complexity. I love to dive in and start changing things to see what happens in situations where it would really be better to write some tests first. And, I like pushing the boundaries of the language, but I don&#8217;t work on experimental or research code &#8211; someone has to read and maintain it &#8211; so all the clever metaprogramming is really not suitable.</p>
<p>But it&#8217;s so much fun! And I get to revel in how smart I am! It sounds stupid to say that out loud, though. So I don&#8217;t even go there.</p>
<h2>The Nine-to-Fiver</h2>
<p>I often hear programmers &#8211; mostly young, mostly single &#8211; talk  disparagingly about &#8220;commodity programmers.&#8221; They usually mean people  who program at work but spend their free time on other stuff, and aren&#8217;t  really interested in tech.</p>
<p>Since I became a parent, I&#8217;ve turned into that person &#8211; the one who  needs to leave at a fixed time and can&#8217;t work weekends. So for a lot of my peers, that means I&#8217;m not &#8220;passionate&#8221; enough, and that I can&#8217;t really be a  good engineer. I got that reaction enough times that I started  to believe it. Well, fuck that. I know I am amazing at what I do, and I  love it. But it&#8217;s not my whole life.</p>
<p>Working at a company that really respects the boundaries of my time AND enables me to kick ass and get shit done all day has seriously been a revelation.</p>
<h2>Socialitis</h2>
<p>On the spectrum of social awkwardness, I fall somewhere between the  engineers and the marketing guys. Like many engineers, I miss social  cues, don&#8217;t make enough eye contact, forget people&#8217;s names, and have a  hard time making small talk. However, I can fake these skills decently  well when necessary, and I&#8217;ve noticed that it&#8217;s a muscle that I can  exercise &#8211; the more I do it, the better I get, and the less I have to  think about it.</p>
<p>About a month after I started at Pivotal, I went to a UCSD engineering alumni  event. At these events, where I am  usually the only person not working in Enterprise with a capital E, the  social interaction part of the evening is a lot of guys staring at each  other&#8217;s shoes. In the past I&#8217;ve tried to get conversation out of these  people, but between their awkwardness and mine it was like  pulling teeth. But this time, for some non-obvious reason&#8230;it was easy.  The people and the shoes were about the same.</p>
<p>It&#8217;s me who had changed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/04/14/thoughts-on-two-months-of-pairing/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>SCALE 8x Slides Posted</title>
		<link>http://www.sarahmei.com/blog/2010/02/20/scale-8x-slides-posted/</link>
		<comments>http://www.sarahmei.com/blog/2010/02/20/scale-8x-slides-posted/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 00:07:13 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[scale8x]]></category>
		<category><![CDATA[sfruby]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=326</guid>
		<description><![CDATA[Yesterday I did a talk at SCALE 8x called &#8220;Moving the Needle: How SF Ruby Got to 18%.&#8221; Broadly, the topic was how to get more women into a technical community. I talked about how, specifically, we took the SF Ruby monthly meetups from 2% women to 18% women over the past year.
Short version: it [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I did a talk at <a href="http://www.socallinuxexpo.org/scale8x/">SCALE 8x</a> called &#8220;<a href="http://www.socallinuxexpo.org/scale8x/presentations/moving-needle-how-san-francisco-ruby-community-got-18">Moving the Needle: How SF Ruby Got to 18%</a>.&#8221; Broadly, the topic was how to get more women into a technical community. I talked about how, specifically, we took the <a href="http://meetup.com/sfruby">SF Ruby</a> monthly meetups from 2% women to 18% women over the past year.</p>
<p>Short version: it was a lot of work.<br />
<span id="more-326"></span><br />
A lot of people have asked us about this, though, so it seemed worth distilling. The slides don&#8217;t convey everything I talked about. In the next few weeks I&#8217;d like to try putting together a blog post that does a better job. But for now, here they are.</p>
<p><strong>Update (3/6/2010):</strong> <a href="http://audio.socallinuxexpo.org/Friday/WIOS/talk%20%235%20(Sarah%20Mei).mp3">MP3 audio is now available</a> &#8211; thanks SCALE folks! Also, I&#8217;ve posted a <a href="http://www.sarahmei.com/blog/wp-content/uploads/2010/03/SCALE-WIOS.pdf">PDF version of the slides</a> for those of you without flash.</p>
<div style="width:425px;text-align:left;padding-left:20px;" id="__ss_3234356"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/sarahmei/moving-the-needle-how-sf-ruby-got-to-18" title="Moving the Needle: How SF Ruby Got to 18%">Moving the Needle: How SF Ruby Got to 18%</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=scale-wios-100220162111-phpapp02&#038;stripped_title=moving-the-needle-how-sf-ruby-got-to-18" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=scale-wios-100220162111-phpapp02&#038;stripped_title=moving-the-needle-how-sf-ruby-got-to-18" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more presentations from <a style="text-decoration:underline;" href="http://www.slideshare.net/sarahmei">Sarah Mei</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/02/20/scale-8x-slides-posted/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>LARubyConf Slides Posted</title>
		<link>http://www.sarahmei.com/blog/2010/02/20/larubyconf-slides-posted/</link>
		<comments>http://www.sarahmei.com/blog/2010/02/20/larubyconf-slides-posted/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 21:39:55 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[larubyconf]]></category>
		<category><![CDATA[teaching]]></category>
		<category><![CDATA[workshops]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=309</guid>
		<description><![CDATA[Just finished my LA Ruby Conf talk on teaching Ruby to kids. Here are a few further resources:


Shoes &#8211; a simple way to create desktop applications in Ruby. Cross-platform, pure awesome. (code on github)
Hackety Hack &#8211; built on Shoes, this is a toolkit specifically for learning how to program.
Small Ruby &#8211; learn to program for [...]]]></description>
			<content:encoded><![CDATA[<p>Just finished my LA Ruby Conf talk on teaching Ruby to kids. Here are a few further resources:<br />
<span id="more-309"></span></p>
<ul>
<li><a href="http://shoes.heroku.com/">Shoes</a> &#8211; a simple way to create desktop applications in Ruby. Cross-platform, pure awesome. (<a href="http://github.com/shoes/shoes">code on github</a>)</li>
<li><a href="http://hacketyhack.heroku.com/">Hackety Hack</a> &#8211; built on Shoes, this is a toolkit specifically for learning how to program.</li>
<li>Small Ruby &#8211; learn to program for the smaller set &#8211; think turtle drawing. Coming soon.</li>
<li><a href="http://www.sarahmei.com/blog/wp-content/uploads/2010/03/LARubyConf.pdf">PDF version of the slides</a> (exactly the same as slides below)</li>
</ul>
<div style="width:425px;text-align:left;padding-left:15px;" id="__ss_3233891"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/sarahmei/teaching-ruby-to-kids" title="Teaching Ruby to Kids">Teaching Ruby to Kids</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=larubyconf-100220140747-phpapp01&#038;stripped_title=teaching-ruby-to-kids" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=larubyconf-100220140747-phpapp01&#038;stripped_title=teaching-ruby-to-kids" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more presentations from <a style="text-decoration:underline;" href="http://www.slideshare.net/sarahmei">Sarah Mei</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/02/20/larubyconf-slides-posted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The First 2010 Ruby Outreach Workshop</title>
		<link>http://www.sarahmei.com/blog/2010/02/19/the-first-2010-ruby-outreach-workshop/</link>
		<comments>http://www.sarahmei.com/blog/2010/02/19/the-first-2010-ruby-outreach-workshop/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 17:37:54 +0000</pubDate>
		<dc:creator>sarahmei</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[childcare]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[sfruby]]></category>
		<category><![CDATA[workshops]]></category>

		<guid isPermaLink="false">http://www.sarahmei.com/blog/?p=301</guid>
		<description><![CDATA[&#8230;is now open for registration.  Last year Sarah Allen and I did three workshops for women and this year we&#8217;re going for four.  So, if you&#8217;d like to learn Rails and can come BOTH Friday, February 26th in the evening AND Saturday, February 27th during the day, go sign up! There are only [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_171" class="wp-caption alignright" style="width: 210px"><img src="http://www.sarahmei.com/blog/wp-content/uploads/2009/07/ruby.jpg" alt="Copyright 2006 by Yukihiro Matsumoto" title="ruby" width="200" class="size-full wp-image-171" /><p class="wp-caption-text">LEARN ME</p></div>
<p>&#8230;is now <a href="http://www.meetup.com/sfruby/calendar/12605445/">open for registration</a>.  Last year <a href="http://ultrasaurus.com">Sarah Allen</a> and I did three workshops for women and this year we&#8217;re going for four.  So, if you&#8217;d like to learn Rails and can come BOTH Friday, February 26th in the evening AND Saturday, February 27th during the day, <a href="http://www.meetup.com/sfruby/calendar/12605445/">go sign up</a>! There are only a few spots left.</p>
<p>And yep, still free.</p>
<p>We&#8217;re also seeking Rails developers (of any gender) to assist as TAs. <a href="http://www.meetup.com/sfruby/calendar/12605400/">Tell us about that here</a>.  Past TAs and teachers have found it quite rewarding. Plus you get a drink ticket for the afterparty. <img src='http://www.sarahmei.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>And finally, some logistics: it&#8217;ll be in an office space in downtown San Francisco, near transit. Next week we&#8217;ll send out the exact address. We&#8217;ll have informal childcare and space for pumping or nursing &#8211; please tell us if you think you&#8217;ll be using those services when you register.</p>
<p>See you there! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.sarahmei.com/blog/2010/02/19/the-first-2010-ruby-outreach-workshop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
