<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>MettaProgramming</title>
	<atom:link href="http://mettadore.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mettadore.com</link>
	<description>Thoughts on Software and Technology</description>
	<lastBuildDate>Mon, 09 Apr 2012 19:11:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Bundle update &#8220;killed:&#8221; Watch those log files in your gems!</title>
		<link>http://mettadore.com/ruby/bundle-update-killed-watch-those-log-files-in-your-gems/</link>
		<comments>http://mettadore.com/ruby/bundle-update-killed-watch-those-log-files-in-your-gems/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 19:11:59 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=1028</guid>
		<description><![CDATA[Today was supposed to be a normal day. A simple pull-request merge, an automated Jenkins build, and then a database migration. What followed instead was a search for the cause of a build failure– or, rather, the cause of a ruby gem that was causing the build failure. The Problem The only hint I had [...]]]></description>
			<content:encoded><![CDATA[<p>Today was supposed to be a normal day. A simple pull-request merge, an automated Jenkins build, and then a database migration.</p>
<p>What followed instead was a search for the cause of a build failure– or, rather, the cause of a ruby gem that was <em>causing</em> the build failure.</p>
<h3>The Problem</h3>
<p>The only hint I had to go on was this message in my Jenkins console:</p>
<pre class="brush: bash; title: ; notranslate">
Installing acts_permissive (0.3.2) /tmp/hudson7424891008093103684.sh: line 5: 12423
Killed
bundle
Build step 'Execute shell' marked build as failure
</pre>
<p>It couldn&#8217;t install the gem? Why? To the console:</p>
<pre class="brush: bash; title: ; notranslate">
jenkins@li128-183:~/workspace/musicstand
$ bundle update acts_permissive
Fetching source index for http://rubygems.org/
Using rake (0.9.2.2)
Using RedCloth (4.2.9)
...

NoMemoryError: failed to allocate memory
An error occured while installing acts_permissive (0.3.2), and Bundler cannot continue.
Make sure that `gem install acts_permissive -v '0.3.2'` succeeds before bundling.
</pre>
<p>What the what? Sadly, trying it manually was no help:</p>
<pre class="brush: bash; title: ; notranslate">
jenkins@li128-183:~/workspace/musicstand
$ gem install acts_permissive -v '0.3.2'
Killed
</pre>
<p>That&#8217;s it. Nothing else.</p>
<h3>The Investigation</h3>
<p>Luckily<sup><a href="http://mettadore.com/ruby/bundle-update-killed-watch-those-log-files-in-your-gems/#footnote_0_1028" id="identifier_0_1028" class="footnote-link footnote-identifier-link" title="or, unluckily, as the case may be">1</a></sup> I am the writer of the Gem in question. <a href="http://rubygems.org/gems/acts_permissive">ActsPermissive</a> is an instance-specific permissions system based on &#8220;circles of trust&#8221; (a bit like Google+ circles).</p>
<p>I went to my dev folder for the gem and explored it. Nothing seemed out of the ordinary. So I created a new gemset and ran &#8220;bundle install&#8221; forcing an installation of acts_permissive. It installed fine; however, I did notice that Bundler seemed to &#8220;pause&#8221; while installing it. On a hunch, I went to look at what the size of the .gem file was.</p>
<h3>The Solution</h3>
<p>Embarrassing as it is, the .gem file weighed in at a whopping 23M. That&#8217;s just ridiculous for a few text files! Further investigation showed me that my development directory was a full Gig! What the what?</p>
<p>Log files.</p>
<p>Without thinking, I was including the spec/dummy rails application, which contains a log directory, and log/test.log was nearly a gigabyte in size! Consequently, that was all getting packaged up, and then this 1G gem was trying to be compressed on the server and borking because of failed memory!</p>
<p>Lazy, John!</p>
<p>I had the normal &#8220;s.test_files = Dir["spec/**/*"] line in my gemspec, but need to exclude some files. The &#8220;test_files&#8221; attribute is an array, thus, I added the following lines to my .gemspec:</p>
<pre class="brush: ruby; title: ; notranslate">
  s.test_files = Dir[&quot;spec/**/*&quot;]
  s.test_files.delete(&quot;spec/dummy/log&quot;)
  s.test_files.delete(&quot;spec/dummy/log/development.log&quot;)
  s.test_files.delete(&quot;spec/dummy/log/test.log&quot;)
</pre>
<p>This dropped the .gem file back to a few kilobytes, which is all it should ever be. </p>
<h3>Coda</h3>
<p>It took a bit of detective work, but the &#8220;bundle update &#8216;killed&#8217;&#8221; problem was a crisis averted. This would&#8217;ve been grueling to troubleshoot if I didn&#8217;t own the acts_permissive gem. However, in the interest of helping others, it can be pretty easy to at least rule this problem out if your &#8216;gem install&#8217; or &#8216;bundle update&#8217; fails mysteriously. Grab the .gem file from RubyGems and check the size. If it&#8217;s crazy huge like acts_permissive was, then you might just be filling up RAM when it&#8217;s extracted.</p>
<ol class="footnotes"><li id="footnote_0_1028" class="footnote">or, unluckily, as the case may be</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/ruby/bundle-update-killed-watch-those-log-files-in-your-gems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trolling, Sexism, and Dealing with Disappointment</title>
		<link>http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/</link>
		<comments>http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 19:53:50 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=1015</guid>
		<description><![CDATA[This past week has been one is extreme disappointment for me as I survey the landscape of my beloved profession. From Portland&#8217;s own Postgres genius Selena Deckelman getting hazed on IRC to the incredibly immature sexism of Sqoot listing women as &#8220;a feature&#8221; of a hackathon I&#8217;ve just been feeling really depressed that there is [...]]]></description>
			<content:encoded><![CDATA[<p>This past week has been one is extreme disappointment for me as I survey the landscape of my beloved profession. From Portland&#8217;s own Postgres genius <a href="https://twitter.com/#!/selenamarie/status/182841043786543105">Selena Deckelman</a> getting hazed on IRC to the incredibly immature sexism of <a href="http://www.readwriteweb.com/enterprise/2012/03/how-casual-sexism-put-sqoot-in.php">Sqoot listing women as &#8220;a feature&#8221; of a hackathon</a> I&#8217;ve just been feeling really depressed that there is this scale of stupidity toward our fellow programmers– our fellow people– in a field where, at one time, we&#8217;ve all known what it&#8217;s like to feel out of place and unaccepted.</p>
<p>Sqoot is just a light on what&#8217;s seemingly rampant in a field where I just assume there are awesome women doing awesome things. How much of this stupidity am I unaware of? How much do I add to it. Does it really make us feel better to treat other people like shit?</p>
<h3>Sexism At Hydrasi</h3>
<div id="attachment_1017" class="wp-caption alignleft" style="width: 181px"><a href="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.16.15-PM.png"><img class="size-full wp-image-1017" title="Screen Shot 2012-03-23 at 12.16.15 PM" src="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.16.15-PM.png" alt="" width="171" height="171" /></a><p class="wp-caption-text">Kerridra and SI1138, Hydrasi&#39;s lovable mascots</p></div>
<p>It strikes me as somewhat odd that I am a man, in an really male dominated field, in a male dominated world, who&#8217;d write about this. I mean, what do I know? Just as with white people who don&#8217;t see things that every person of color takes for granted, I&#8217;m sure there are a great many things than I just blindly ignore in my happy placement of gender-based privilege. In fact, I know there are.</p>
<p>Recently, we were having some graphic design work done for Hydrasi.<sup><a href="http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/#footnote_0_1015" id="identifier_0_1015" class="footnote-link footnote-identifier-link" title="These images are secret, don&amp;#8217;t tell anyone you saw them!">1</a></sup> Hydrasi has a lot of inside jokes based on our name<sup><a href="http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/#footnote_1_1015" id="identifier_1_1015" class="footnote-link footnote-identifier-link" title="Oh no, it broke! It&amp;#8217;s Brokedrasi!">2</a></sup> and our mascots, one of which is a Sasquatch and one is a cute, blue robot.<sup><a href="http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/#footnote_2_1015" id="identifier_2_1015" class="footnote-link footnote-identifier-link" title="The Star Wars connection here is obvious, but there are others we play with as well">3</a></sup></p>
<p>The short story is that there are tiers of service, and for the top &#8220;enterprise&#8221; tier we were trying to make yet another cultural reference joke that could have gone bad.</p>
<p>For every tier, we have a different image. The free tier shows our Sasquatch, Kerridra, holding a pitchfork, the next tier– the lowest paid tier– shows Kerridra with his robotic companion SI1138. The idea, of course, is that you get more robots, more power, with higher subscription rates.</p>
<div id="attachment_1018" class="wp-caption alignright" style="width: 310px"><a href="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.09.35-PM.png"><img class="size-medium wp-image-1018 " title="Screen Shot 2012-03-23 at 12.09.35 PM" src="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.09.35-PM-300x81.png" alt="" width="300" height="81" /></a><p class="wp-caption-text">Attempt at referencing Madmen</p></div>
<p>At the top tier, the enterprise tier, I thought it would be fun to have a reference to the TV show Madmen, where rich advertising executives have martini parties and red-headed secretaries wear mini skirts. My thought here was not &#8220;focus on red-headed chics in mini-skirts&#8221; but rather on &#8220;At the enterprise level, we take care of everything for you so you can sit back and drink a martini.&#8221; Here&#8217;s the first rough cut of that design.</p>
<div id="attachment_1023" class="wp-caption alignleft" style="width: 310px"><a href="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.27.57-PM.png"><img class="size-medium wp-image-1023" title="Screen Shot 2012-03-23 at 12.27.57 PM" src="http://mettadore.com/files/2012/03/Screen-Shot-2012-03-23-at-12.27.57-PM-300x79.png" alt="" width="300" height="79" /></a><p class="wp-caption-text">The final version. You get a computing rack, NOT a secretary</p></div>
<p>Again, the idea was to have something immediately identifiable as from the show Madmen, but we looked at it and felt that it came off as sexist, pointless, and sort of missing the point of what it means to be at the upper level of service. In the end we axed my Madmen idea and went with another reference, this one not to a cultural reference, but to service. We put a rack of servers behind Kerridra and decided to say &#8220;You are getting people, robots, and servers&#8221; instead of &#8220;You can get a hot red-head.&#8221;</p>
<h3>Mindless Sexism</h3>
<p>There&#8217;s a large part of me that&#8217;s embarrassed at the whole idea. I mean, I was just trying to go for a funny pop-culture reference in the same way as we have Star Wars references and WALL-E references. In the end, we recognized it as a misplaced, and overly sexist image, and decided to pull it before it ever went anywhere, but how many things like this don&#8217;t get pulled?</p>
<p>I guess the take away is that we did sit down, and make a conscious decision to axe that train of thought because if it&#8217;s overtones. We thought about it, we decided. That&#8217;s sort of what worries me. How much do we– all of us– throw out there because we <em>don&#8217;t </em>think about it. How much is just simply cultural privilege that we swim in like water?</p>
<h3>Seeking The Positive</h3>
<p>This week kind of got me down, both because of the shitty nature of the way things are, and because of my worry (as my wife and I watch her belly grow and I, at least, hope for two daughters) that I add to it as much as anyone.</p>
<p>I guess one thing to look toward positively is a responses to everything this week. Responses like Selena&#8217;s. She chose not to battle, but to, almost quietly, Storify the interaction and then ask for feedback (http://bit.ly/GW1XT7). This was an incredibly mature and awesome way to handle a troll (Cheers to you, Selena, for so much restraint and thoughtfulness). And there was a lot of outrage about Sqoot&#8217;s mindless objectification of women, including <a href="http://blog.tommorris.org/post/19778985050/newsflash-sexism-in-geek-communities-demeans-everybody">posts like this by Tom Morris</a>. There&#8217;s a lot of outrage and a lot of people, not only women, saying &#8220;Why is it this way? It doesn&#8217;t have to be, and you need to stop perpetuating it!&#8221; That&#8217;s positive.</p>
<p>For what it&#8217;s worth, Sqoot apologized with a &#8220;<a href="http://blog.sqoot.com/we-can-do-better-an-apology-from-sqoot">we can do better</a>&#8221; post. This made me feel worse instead of better because it just seemed way too late and seemed to radiate insincerity. The only thing I could think of while reading that was an image of Steve Carrell from The Office, spouting an apology speech which had all of the right words that he knew other people would want him to say.</p>
<h3>Coda</h3>
<p>Overall, it&#8217;s been a disappointing week in Tech. I&#8217;m trying to see the positive. Good, strong, well-reasoned responses to stupidity and sexism. That should make me feel good. But the fact that there&#8217;s such a culture of &#8220;brogramming&#8221; makes me feel sad. I hope we can change that, but I&#8217;d really expected it to have been changed by now, so am not sure how much faith I have in me and my fellow <em>man</em>.</p>
<ol class="footnotes"><li id="footnote_0_1015" class="footnote">These images are secret, don&#8217;t tell anyone you saw them!</li><li id="footnote_1_1015" class="footnote">Oh no, it broke! It&#8217;s Brokedrasi!</li><li id="footnote_2_1015" class="footnote">The Star Wars connection here is obvious, but there are others we play with as well</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/trolling-sexism-and-dealing-with-disappointment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Redis-backed acts_as_follower gem</title>
		<link>http://mettadore.com/ruby/a-redis-backed-acts_as_follower-gem/</link>
		<comments>http://mettadore.com/ruby/a-redis-backed-acts_as_follower-gem/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 16:23:01 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=1009</guid>
		<description><![CDATA[I usually start blog-based introductions to gems and libraries that I write with a narrative. Lately, however, I&#8217;ve been getting busier keeping up with the work I need to do for clients and that I need to do for my startup. So I&#8217;ll leave the narrative to a minimum, a very short question. You love [...]]]></description>
			<content:encoded><![CDATA[<p>I usually start blog-based introductions to gems and libraries that I write with a narrative. Lately, however, I&#8217;ve been getting busier keeping up with the work I need to do for clients and that I need to do for my startup. So I&#8217;ll leave the narrative to a minimum, a very short question.</p>
<p>You love the acts_as_follower gem, right? Sure, everyone does. Wouldn&#8217;t it be better if it was based in Redis? Sure, of course it would.</p>
<p>This weekend I found the great <a href="https://github.com/agoragames/amico">Amico gem</a>, a low-level Ruby gem for Redis backed followers, and I decided to create <a href="https://github.com/mettadore/acts_as_amico">Acts_as_Amico</a>, a Rails injectable gem that uses that back-end ability, so now you can have a followers gem that is completely in Redis right in your Rails app.</p>
<p>The code has full-ish, but ever expanding, documentation on the Github page, but here&#8217;s a quick rundown</p>
<h3>ActiveRecord Objects</h3>
<pre class="brush: ruby; title: ; notranslate">
class User &lt; ActiveRecord::Base
 acts_as_amico
end

usera = User.create
userb = user.create

usera.follow! userb
=&gt; nil

usera.following? userb
 =&gt; true
</pre>
<h3>Advanced Usage</h3>
<pre class="brush: plain; title: ; notranslate">
class Admin &lt; ActiveRecord::Base
  acts_as_amico :amico_key =&gt; :name
  validates_uniqueness_of :name  # -&gt; do this or be sorry
  validates_presence_of :name # -&gt; this too, you've been warned
end

usera = User.create

puts usera.id
 =&gt; 18

admin = Admin.create :name =&gt; &quot;frank&quot;

usera.follow! admin
 =&gt; nil

admin.follow! usera
 =&gt; [1, 1]

admin.followers
 =&gt; [&quot;18&quot;]

usera.followers
 =&gt; [&quot;frank&quot;]
</pre>
<h3>ActiveResource Objects</h3>
<pre class="brush: ruby; title: ; notranslate">
class RestObject &lt; ActiveResource::Base
  self.site = &quot;http://mettadore.com/junk&quot;
  acts_as_amico :amico_key =&gt; :title
end

usera = User.create

rest_object = RestObject.find(123)

rest_object.title
 =&gt; &quot;Bread and Circus&quot;

usera.follow! rest_object

usera.following? rest_object
 =&gt; true

usera.following
 =&gt; [&quot;Bread and Circus&quot;]
</pre>
<h3>Issues</h3>
<p>I have every expectation that there will be problems and bugs. If you find one, please don&#8217;t hesitate to <a href="https://github.com/mettadore/acts_as_amico/issues">file an issue if</a> you&#8217;re on Github, or <a href="http://johnmetta.com/+">send me a message on Google+</a> if you&#8217;re not.</p>
]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/ruby/a-redis-backed-acts_as_follower-gem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Redis Gems]]></series:name>
	</item>
		<item>
		<title>Rails: SQL Injection over Configuration</title>
		<link>http://mettadore.com/analysis/rails-sql-injection-over-configuration/</link>
		<comments>http://mettadore.com/analysis/rails-sql-injection-over-configuration/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 17:59:50 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[convention]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SQL injection]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=991</guid>
		<description><![CDATA[It was an interesting weekend for the Github team, the Rails core team, and lots of Rails users who worked at all through the weekend. There are a lot of details about the weekend to discuss, but my main discussion point is one of philosophy and intention of the Rails project. We&#8217;ll get to that [...]]]></description>
			<content:encoded><![CDATA[<p>It was an interesting weekend for the Github team, the Rails core team, and lots of Rails users who worked at all through the weekend. There are a lot of details about the weekend to discuss, but my main discussion point is one of philosophy and intention of the Rails project. We&#8217;ll get to that towards the end. First, a bit of background.</p>
<h3>Hacking Github</h3>
<p>This weekend, a Github user named <a href="https://github.com/homakov">Egor Homakov</a> hacked Github in such a way that allowed him to <a href="https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57">commit directly to the Rails core</a> project. Since Homakov is not a Rails team member, this is a really big deal.</p>
<p>Since this happened, there&#8217;s been a lot of talk about the Rails core being fundamentally insecure. In fact, <a href="https://github.com/rails/rails/issues/5239">Homakov has been harping on this for at least 1000 years</a>. A few days ago he filed an issue about a <a href="https://github.com/rails/rails/issues/5228">mass assignment vulnerability</a> in the Rails core, and later he illustrated this vulnerability by filing an <a href="https://github.com/rails/rails/issues/5239">issue report from the future</a>. He was illustrating that you can inject attributes into a Rails model with an HTTP request.</p>
<p>So, when no-one took him seriously, he took the next step. He created HTTP PUT requests adding his SSH key to a Rails core user id, then <a href="https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57">pushed a commit directly to Rails core</a>.</p>
<h3>How to Hack Rails</h3>
<p>It turns out that Rails apps, by default, are easy to hack. Peter Nixey wrote a very detailed post about <a href="https://gist.github.com/1978249">how Homakov hacked Github and the one line of code that could have prevented it</a>, so if you want the full details, read there. The summary is much shorter.</p>
<p>Let&#8217;s create a simple User model which has two attributes, <code>name</code> and <code>role</code>. By default, every attribute of every model can be modified by using <code>update_attributes</code>. We all know this, and we&#8217;ve known it for a while. What it means is that any User, even if they don&#8217;t have permission, can update their own role. Imagine if I log in to our example app and submit a PUT request to the UsersController with the package <code>{'params': {'id': 23, 'role': 'superadmin'} }</code>. By default, the app will accept this and update the user with the new role.</p>
<p>This is exactly what Homakov did. He sent an HTTP request to Github and used update_attributes to change the Github database. All of this could, he argued, be prevented by adding attr_accessor to the User model.</p>
<h3>Rails: Convention over <del>Configuration</del> Security</h3>
<p>Now, the philosophical point I want to make about this is that the Rails core team seems to be ignoring their own mantra. All of us know that Rails adheres strongly to the <a href="http://en.wikipedia.org/wiki/Convention_over_configuration">Convention over Configuration</a> design pattern. It&#8217;s a pattern that Rails users are taught from day one. In fact, it&#8217;s embedded in the framework&#8217;s <em>name</em>.<sup><a href="http://mettadore.com/analysis/rails-sql-injection-over-configuration/#footnote_0_991" id="identifier_0_991" class="footnote-link footnote-identifier-link" title="Look, just stay on these rails and you&amp;#8217;ll move fast. We&amp;#8217;re not responsible for what happens if you go over there">1</a></sup></p>
<p>One of the outcomes of Convention over Configuration is that sensible defaults should be, well, sensible. The Rails core team feel strongly that attr_accessor should not be a default<sup><a href="http://mettadore.com/analysis/rails-sql-injection-over-configuration/#footnote_1_991" id="identifier_1_991" class="footnote-link footnote-identifier-link" title="Incidentally, I don&amp;#8217;t either, but you can set this as the default by using ActiveRecord::Base.send(:attr_accessible, nil), but this causes all sorts of problems">2</a></sup> and that security is the responsibility of the app developer. I agree that security is our responsibility, but disagree that the dominant Rails design-pattern-come-mantra supports this.</p>
<p>It&#8217;s almost as if no-one wants to say &#8220;Yeah, we should really take care of this.&#8221; Everyone is saying &#8220;You know, <em>you</em> should really take care of this.&#8221;</p>
<h3>Stop the world! We&#8217;ve found a SQL injection</h3>
<p>There&#8217;s a term that makes all software developers give pause: &#8220;SQL Injection.&#8221; It&#8217;s a phrase that keeps us lying awake at night, and gives us nightmares when we finally fall asleep. The idea that someone, using nothing more than a web browser, can change our database willy nilly. It&#8217;s a terrifying thought.</p>
<p>I can&#8217;t help but take an initial read of all the hubbub and think that we&#8217;re not giving it the importance that it&#8217;s due. Everyone sees a headline saying Rails has a &#8216;mass assignment vulnerability&#8217; and says to themselves &#8216;I should probably look into that at some point.&#8217; It&#8217;s too vague, to uncertain. To unemotional.<sup><a href="http://mettadore.com/analysis/rails-sql-injection-over-configuration/#footnote_2_991" id="identifier_2_991" class="footnote-link footnote-identifier-link" title="In fact, to be honest, that&amp;#8217;s how I was reading it.">3</a></sup></p>
<p>I have to assume that everyone would be treating this differently if we called it what it is. Imagine your thoughts (and actions) if you read a different headline, something like &#8220;Rails apps prone to SQL injection by default&#8221;</p>
<p>Don&#8217;t you think you&#8217;d get something done? You should, because that&#8217;s what we&#8217;re talking about. This is a path to SQL injection, full stop.</p>
<h3>Who owns this issue</h3>
<p>I love Ruby on Rails. Like Python, Scala, Node.js, and a host of other technologies that we have at our disposal, Ruby&#8217;s web framework makes being a developer both powerful and fun. There&#8217;s so much we can do– and so much we can do <em>very quickly</em>. But there&#8217;s a cost to pay. Convention over Configuration is a good thing, but we can&#8217;t expect people to learn fast, develop fast– create fast– if we don&#8217;t respect the logical outcome of that philosophy.</p>
<p>That outcome is this: We, Rails developers, understand that we are responsible for our security; however, we also <em>believe</em> in you, the Rails core team. We trust you. We believe it when you tell us to follow &#8220;Convention over Configuration,&#8221; and so we naturally believe that the defaults you give us will be a safe, or at least not horribly, dangerously wrong. We, all of us– developers and Rails core team both– can&#8217;t have it both ways. We are telling ourselves to follow Convention over Configuration, but we&#8217;re also telling ourselves that SQL Injection is <em>a viable convention</em>, thus, that we have <em>security as a configuration</em>.</p>
<p>Now, personally, I don&#8217;t believe that attr_accessor belongs in the model– or at least that security from view-based actions belongs in the model. Rails is an MVC framework, and therefore I don&#8217;t like forcing myself to define my <em>model</em> based on actions in the <em>view</em>. I don&#8217;t want my view owning control of my model that way. I think the controller should manage these permissions and there are <a href="http://jonathanleighton.com/articles/2011/mass-assignment-security-shouldnt-happen-in-the-model/">others who feel the same</a>. In fact <a href="https://gist.github.com/1974187">Yehuda Katz argues this as well</a>.</p>
<p>Still, the overall question remains: How can we reconcile the mantra of Convention over Configuration if we support the standard of dangerous insecurity by convention?</p>
<ol class="footnotes"><li id="footnote_0_991" class="footnote">Look, just stay on these rails and you&#8217;ll move fast. We&#8217;re not responsible for what happens if you go over there</li><li id="footnote_1_991" class="footnote">Incidentally, I don&#8217;t either, but you can set this as the default by using <code>ActiveRecord::Base.send(:attr_accessible, nil)</code>, but this causes all sorts of problems</li><li id="footnote_2_991" class="footnote">In fact, to be honest, that&#8217;s how I was reading it.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/rails-sql-injection-over-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Web App Went Live Today</title>
		<link>http://mettadore.com/analysis/a-web-app-went-live-today/</link>
		<comments>http://mettadore.com/analysis/a-web-app-went-live-today/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 21:25:26 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=967</guid>
		<description><![CDATA[A new web app went live today, and I shed a tear. The Power of Good Questions Some history. Years ago, I was starting to question my decision to become a hydrologist. Not because I hated hydrology, I did– and still do– deeply love it, but because I couldn&#8217;t find a job. Since I&#8217;d been [...]]]></description>
			<content:encoded><![CDATA[<p>A new web app went live today, and I shed a tear.</p>
<h3>The Power of Good Questions</h3>
<p>Some history.</p>
<p>Years ago, I was starting to question my decision to become a hydrologist. Not because I hated hydrology, I did– and still do– deeply love it, but because I couldn&#8217;t find a job. Since I&#8217;d been a programmer for 20+ years (indeed, I programmed all the way through 10 years in the sciences), I decided to see what options were out there in that field.</p>
<p>So I interviewed for this software development company. I was nervous because I hadn&#8217;t actually <em>worked</em> as a programmer in a long time. My title had been &#8220;researcher&#8221; and &#8220;scientist&#8221; for a decade. Even though I&#8217;d been programming that entire time, I was nervous about being labeled as a &#8220;wannabe.&#8221;</p>
<p>My interviewer saw through that nervousness right away and immediately started asking me questions that were not the basic &#8220;do you actually know programming&#8221; but were much more geared toward &#8220;what do you think of this subtle programming construct.&#8221;  It was, without a doubt, the best interview experience I ever had, and made me respect the interviewer and want to work with him even if not at this job– which I didn&#8217;t even get.</p>
<p>I never forgot that interview.</p>
<h3>What Goes Around</h3>
<p>Fast forward a few years, and last year I happened to see that same interviewer at the coffee shop. He said that he&#8217;d just left his last job and was looking for work. That, to me, was a wide open door. Finally, a chance to work with this guy!</p>
<p>&#8220;Really,&#8221; I said, &#8220;It&#8217;s not much, but I&#8217;ve got some Ruby work I could use some help with for my company if you&#8217;re interested&#8221;</p>
<p>&#8220;I don&#8217;t know Ruby, I&#8217;ve been learning a little bit, but I can&#8217;t do work in it.&#8221;</p>
<p>&#8220;Tell you what, work with me. I&#8217;ll help you learn Ruby while you do small bits of work on my site. Fair trade?&#8221;</p>
<p>As I suspected from this now barely remembered interview so long ago, he was a sharp tack and things progressed fast enough that he never even did any work on my site. Rather, I took another contract that was a wee bit too big for me, and brought him on as a sub. And so, finally, I was working with this guy, and helping him learn Ruby, and getting him <em>paid</em> to do it.</p>
<h3>A Favor, Returned</h3>
<p>A couple months later, I got contacted by another company who wanted me to create a web app. I was just too busy, so I brought this fellow to the first meeting. My response was, basically, &#8220;I&#8217;m too busy to do this, but I can speak from experience that this fellow here is a good candidate. I&#8217;ll let you take it from here.&#8221; And I walked away. Now, here we are, a couple months after that, and <a href="http://mylunchin.com">MyLunchIn.com</a> has launched for our local restaurant Nora&#8217;s Table. It&#8217;s another Rails app that he created, start to finish, entirely free of my involvement.</p>
<p>I don&#8217;t know I started to cry when I placed my first lunch order today. I didn&#8217;t create that site, and honestly, I didn&#8217;t teach this guy Ruby– I just happened to be around while he was teaching himself. But it still feels good.</p>
<p>All those years ago, I was a scientist scared that I wouldn&#8217;t be accepted by &#8220;serious&#8221; developers and I was. It feels good to think that I brought some happiness back to that person, a favor returned. It just feels like this new website is part of a rising tide that floats all of our boats when we work together, when we look out for each other. When we remember a good conversation.</p>
<p>I&#8217;m on my way now to pick up my first ever lunch ordered on this new site. It&#8217;ll be the best tasting lunch I&#8217;ve had in a while.</p>
]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/a-web-app-went-live-today/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Science in Corporate America</title>
		<link>http://mettadore.com/analysis/science-in-corporate-america/</link>
		<comments>http://mettadore.com/analysis/science-in-corporate-america/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 19:16:47 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=963</guid>
		<description><![CDATA[There&#8217;s a bill in Congress called &#8220;The Research Works Act&#8221;1 which threatens open access to science in a very disturbing way. The bill basically gives control of publicly funded research to private companies. There&#8217;s a petition to oppose this bill. I wanted to write up why I think we should sign it. The Research Works [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a bill in Congress called &#8220;<a href="http://thomas.loc.gov/cgi-bin/query/z?c112:H.R.3699:">The Research Works Act</a>&#8221;<sup><a href="http://mettadore.com/analysis/science-in-corporate-america/#footnote_0_963" id="identifier_0_963" class="footnote-link footnote-identifier-link" title="HR3699">1</a></sup> which threatens open access to science in a very disturbing way. The bill basically gives control of <em>publicly funded</em> research to private companies. There&#8217;s <a href="https://wwws.whitehouse.gov/petitions/!/petition/oppose-hr3699-research-works-act/vKMhCX9k">a petition to oppose this bill</a>. I wanted to write up why I think we should sign it.</p>
<h3>The Research Works Act</h3>
<p>Unlike many bills, The Research Works Act has very short text:</p>
<blockquote><p>No Federal agency may adopt, implement, maintain, continue, or otherwise engage in any policy, program, or other activity that&#8211;</p>
<ol>
<li>(1) causes, permits, or authorizes network dissemination of any private-sector research work without the prior consent of the publisher of such work; or</li>
<li>(2) requires that any actual or prospective author, or the employer of such an actual or prospective author, assent to network dissemination of a private-sector research work.</li>
</ol>
</blockquote>
<p>Now, this seems like a reasonable request at first glance. It sounds like we&#8217;re saying &#8220;If private people paid for it, private people should own it,&#8221; right?</p>
<p>Wrong. Let&#8217;s look at the definitions in this bill:</p>
<blockquote><p>In this Act:</p>
<ol>
<li>(1) AUTHOR- The term `author&#8217; means a person who writes a private-sector research work. Such term does not include an officer or employee of the United States Government acting in the regular course of his or her duties.</li>
<li>(2) NETWORK DISSEMINATION- The term `network dissemination&#8217; means distributing, making available, or otherwise offering or disseminating a private-sector research work through the Internet or by a closed, limited, or other digital or electronic network or arrangement.</li>
<li>(3) PRIVATE-SECTOR RESEARCH WORK- <em><strong>The term `private-sector research work&#8217; means an article intended to be published in a scholarly or scientific publication, or any version of such an article</strong></em>, that is not a work of the United States Government (as defined in section 101 of title 17, United States Code), <em><strong>describing or interpreting research funded in whole or in part by a Federal agency and to which a commercial or nonprofit publisher has made or has entered into an arrangement to make a value-added contribution, including peer review or editing</strong></em>. Such term does not include progress reports or raw data outputs routinely required to be created for and submitted directly to a funding agency in the course of research.</li>
</ol>
</blockquote>
<p>What&#8217;s the gist of this? Let&#8217;s look at the National Institutes of Health for an example:</p>
<p>The NIH is a publicly funded institution. Taxpayers– <em>you</em>– pay for its existence. You also pay for the research they do. Because the NIH <em>knows</em> that you pay for their research, when researchers publish papers<sup><a href="http://mettadore.com/analysis/science-in-corporate-america/#footnote_1_963" id="identifier_1_963" class="footnote-link footnote-identifier-link" title="as they are essentially obligated to do by the scientific community">2</a></sup> the require that the researchers also post the research for free, to you, on their website.</p>
<p>You pay for the reasearch, you should have access to it.</p>
<p>The Research Works Act would make that illegal. Under the act, any &#8220;network dissemination&#8221; of that research is illegal. The NIH can&#8217;t offer it to you for free, the scientist can&#8217;t give it away for free. The publishing company owns the information.</p>
<p>You pay for reasearch, you might, if the company wishes it, be able to pay dearly for it… again.</p>
<p>This is wrong.</p>
<h3>Life in a Free Market</h3>
<p>Don&#8217;t get me wrong, I&#8217;m a free market citizen. In fact, I&#8217;m something of a corporate zealot. After spending years working for the government– a proud publicly paid employee– I got completely fed up with the government&#8217;s inability to accomplish what I thought was possible. I left to start a company instead.</p>
<p>I&#8217;m a believer in the corporation. It&#8217;s the nearly perfect problem-solving entity. In fact, I don&#8217;t think of a corporations purpose as &#8220;revenue generation,&#8221; I see their purpose as &#8220;problem solution.&#8221; But they solve those problems within a market, and people <em>pay</em> for the solution, so everyone wins. I believe corporations should be allowed to make money within that market. What I do <em>not</em> believe, is that our government should enshrine a market <em>for</em> the corporation. That&#8217;s not a market, that&#8217;s a baby crib. Nice, protect, safe, with mommy&#8217;s breast readily available.</p>
<p>If the market does not exist, or is not strong enough, then the corporation needs to put its big-boy panties on and get lean, or get lost. Period.</p>
<p>Government should not make laws that take tax-payer funded information and <em>require</em> taxpayers to pay corporations for it again. This is not the protection of the real market, and it is not the protection of market values. This is the governmental protection of corporate profits by creating an <em>unreal</em> market.<sup><a href="http://mettadore.com/analysis/science-in-corporate-america/#footnote_2_963" id="identifier_2_963" class="footnote-link footnote-identifier-link" title="Maybe I&amp;#8217;m wrong. Maybe we should do this. After all, China is doing loads of this and it&amp;#8217;s working out great for them, right?">3</a></sup></p>
<p>Publishers argue that they add value to the work because it is their peer review process that confirms scientific legitimacy.</p>
<p>That&#8217;s complete bullshit. I&#8217;ve been part of this process. It involves me <em>volunteering</em> my time to review a scientific paper. If this is a &#8220;service&#8221; that the publishing companies offer, then they are offering it because thousands of people are working for them for free. The publishing company doesn&#8217;t do this, university scientists, while they are getting public salaries, donate their time to do this. And they&#8217;re mandated to do it, and do it for free. Not by the government, but by the community. I dare you to try to be a scientist without participation in the peer-review process.</p>
<p>The &#8220;added value&#8221; that the publishers offer is essentially the time of public scientists who are volunteering because they <em>have</em> to. The publishing companies make a <em>mint</em> off of this public time. The researchers do the work, do all the writing, and do all the peer review. Meanwhile, the publishing companies rake in amazing profits.<sup><a href="http://mettadore.com/analysis/science-in-corporate-america/#footnote_3_963" id="identifier_3_963" class="footnote-link footnote-identifier-link" title="in the billions, people. Lots of these journal subscriptions are in the thousands or tens of thousands of dollars per year">4</a></sup></p>
<p>I&#8217;m not against all of that. It&#8217;s a great system. Companies taking advantage of a market? Fine. Sounds like a good deal.</p>
<h3>Government Should Not Coddle Corporations!</h3>
<p>But now we have this thing called The Internet. Now we have this idea of &#8220;openness.&#8221; Now we have a public that demands open information, that demands access to the research that they paid for– and we have the tools to give them that access, easily.</p>
<p>In short, we have a market that changed– and a publishing industry that, rather than changing and growing up, sits in its crib crying for mommy&#8217;s breast of federal subsidies.</p>
<p>This bill is not about protecting a real market. This bill is about enshrining a federal subsidy of the scientific publishing industry. Let&#8217;s call it what it is.</p>
<p>If the federal government wants to subsidize the publishing industry to protect its profits, it should say that. If the federal government wants to allow a publishing company to use old-market strategies, by making the new market reality illegal, it should say that. If the federal government wants to restrict access to publicly financed scientific research by putting that research into corporate ownership, it should say that.</p>
<p>And then we&#8217;d all acknowledge that this bill should fail.</p>
<p>If we keep passing federal laws to protect and subsidize companies and markets solely to protect their historic profits in a changing market, we risk ruining the entire idea of a free market altogether. If I have a company and can talk the federal government into passing arbitrary laws that make my company profitable despite market forces, it may seem like a good deal to me. It is emphatically not a good deal to our country.</p>
<p>Publicly funded scientific research should be public. Period. If a company cannot remain profitable given that constraint then the result is simple: The company perishes. It is not Congress&#8217; mission to protect the lives of private companies as if they were fragile fluffy bunnies, protecting them from the big-scary coyote called &#8216;a free market economy.&#8217;</p>
<ol class="footnotes"><li id="footnote_0_963" class="footnote">HR3699</li><li id="footnote_1_963" class="footnote">as they are essentially obligated to do by the scientific community</li><li id="footnote_2_963" class="footnote">Maybe I&#8217;m wrong. Maybe we <em>should</em> do this. After all, China is doing loads of this and it&#8217;s working out great for them, right?</li><li id="footnote_3_963" class="footnote">in the billions, people. Lots of these journal subscriptions are in the thousands or tens of thousands of dollars per year</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/science-in-corporate-america/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New to testing? Just wash one dish</title>
		<link>http://mettadore.com/analysis/new-to-testing-just-wash-one-dish/</link>
		<comments>http://mettadore.com/analysis/new-to-testing-just-wash-one-dish/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 17:39:26 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[one-dish theory]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=957</guid>
		<description><![CDATA[I have a team I&#8217;m working with of great tactical programmers. These guys take the craziest specs you&#8217;ve ever seen from clients and turn them into shit that actually works. Tactical programmers are great, they are needed in every organization. Nothing will get you to a deliverable better than a solid tactical programmer. One thing [...]]]></description>
			<content:encoded><![CDATA[<p>I have a team I&#8217;m working with of great tactical programmers. These guys take the craziest specs you&#8217;ve ever seen from clients and turn them into shit that actually works. Tactical programmers are great, they are needed in every organization. Nothing will get you to a deliverable better than a solid tactical programmer. One thing I&#8217;ve found with many tactical programmers– it&#8217;s almost a universal trait– they don&#8217;t often write tests.</p>
<p>It&#8217;s not that a tactical programmer will <em>never</em> write tests, it&#8217;s just not their focus. They are on the front lines, working, well, tactically. Tests are a strategic issue. To many tactical programmers, tests are not something that are necessary. To the tactical programmer, unit tests are this vague, unimportant, time-consuming thing that someone else tells you that <em>you really should do if you want to have good dental health into your later years.</em> They are not something you need to make this feature work, they are something someone else wants for some unimportant reason.<em><br />
</em></p>
<p>I&#8217;m not going to argue why testing is important. There are enough flies on that carcass. What I want to give, to my team of great tactical programmers, especially, is a concept about writing tests that will make it more palatable.<sup><a href="http://mettadore.com/analysis/new-to-testing-just-wash-one-dish/#footnote_0_957" id="identifier_0_957" class="footnote-link footnote-identifier-link" title="This is not news for seasoned developers, I&amp;#8217;m not saying that it&amp;#8217;s new">1</a></sup></em></p>
<h3>Why Starting To Write Tests Sucks</h3>
<p>The fundamental thing is this: The best way to actually accomplish testing is to start writing tests.</p>
<p>The problem is that you look at this huge codebase you&#8217;ve written without a single test, and you start feeling sick to your stomach and grumpy about your chair and angry at the fact that you&#8217;re coffee is too cold and you say &#8220;Screw that, I don&#8217;t have time for that stupid shit.&#8221;</p>
<p>So, what do you do? You write another feature, that adds more untested code to your codebase, that makes you even <em>more</em> sick to your stomach the next time you think about tests.</p>
<p>And before you know it, the only thing you actually <em>know</em> about tests is this: Those fucking things make me sick to my stomach!</p>
<h3>The One-Dish Theory of Work</h3>
<p>When I clean my house, I don&#8217;t start and say &#8220;I&#8217;m going to clean the house.&#8221; There&#8217;s too much to do, too much to even think about. I start in the kitchen– but I hate cleaning, so I can&#8217;t even think about <em>the kitchen</em>. When I clean my house, I start by going to the sink and washing, not everything in the sink, but one, single dish.</p>
<p>I tell myself, &#8220;I&#8217;m going to wash one dish and see where I go.&#8221;</p>
<p>The thing is, of course, that soaping the sponge, washing that dish, and putting it away requires a small amount of set-up. Thus, when I&#8217;m done washing that one dish, it&#8217;s much easier to wash <em>just one <strong>more</strong> dish.</em> I mean, I&#8217;m already there, and I&#8217;ve got the sponge in my hand.</p>
<p>Before I know it, all the dishes are washed, and the counter next to my sink is clean. Well, with one clean counter, it&#8217;s easier to clean off this other counter. I&#8217;ll just clean <em>this one other counter</em>.</p>
<h3>Just Write One Test</h3>
<p>That&#8217;s how a non-test writing, tactical programmer can think about writing tests. Just write <em>one</em>. Because here&#8217;s the thing: It&#8217;s not that bad. The reason it&#8217;s not that bad is that <em>the best way to accomplish testing is to start writing tests</em>.</p>
<p>Not <em>all</em> of the tests. Just <em>one</em> test.</p>
<p>The beauty of testing is that they work no matter how many you have. You don&#8217;t have to wait until you have time to go back and write tests for <em>everything</em> all at once. If you just start writing tests for the things you work on <em>today</em>, <strong><em>now</em></strong>, then it&#8217;s not such a big task. Don&#8217;t write tests for every class in your codebase, but write tests for this one, small class you&#8217;re working on today.</p>
<p>Write <em>one test</em>, for just this <em>one method</em> in this one, small class, that you are working on <em>today</em>. Tomorrow, write <em>one</em> test for what you&#8217;re working on then. Maybe write <em>two</em> if you&#8217;re feeling cheeky.</p>
<p>What you&#8217;ll find is that, as you write tests here and there, for just the thing you&#8217;re working on, it gets easier and easier. Very soon, you&#8217;ll say &#8220;Well, I was going to just write a test for just that one method, but since I&#8217;m here in the test class, it&#8217;ll only take me another 20 minutes to write tests for _all_ the methods, so I might as well.&#8221; By the time you have a few weeks to actually fill in the rest of the tests, it might only take a few days, because you&#8217;ve been doing it and are more familiar.</p>
<p>Just write <em>one</em> test. Just one. You can decide after you write that one whether you want to write another, but at least write one.</p>
<p>Today.</p>
<ol class="footnotes"><li id="footnote_0_957" class="footnote">This is not news for seasoned developers, I&#8217;m not saying that it&#8217;s <em>new</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/new-to-testing-just-wash-one-dish/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Ever-Deployable Github Workflow, v2.0: Branches and Issues</title>
		<link>http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/</link>
		<comments>http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 19:31:33 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=878</guid>
		<description><![CDATA[Here at CHOAM, we love to live at the junction of creating and learning. In fact, it&#8217;s one of the primary reasons I became a programmer. As a little kid with my TI 99/4A I could create software I never dreamed possible. Sitting down with my BASIC compiler, I could type a few lines of [...]]]></description>
			<content:encoded><![CDATA[<p>Here at <a title="Combine Honnete Ober Advancer Mettadore" href="https://github.com/mettadore">CHOAM</a>, we love to live at the junction of <em>creating</em> and <em>learning</em>. In fact, it&#8217;s one of the primary reasons I became a programmer. As a little kid with my TI 99/4A I could create software I never dreamed possible. Sitting down with my BASIC compiler, I could type a few lines of code and suddenly do something that I could never do before. I&#8217;ve been creating ever since, the ability to create was too addictive to let go.</p>
<p>Software is a world where you need to improve your skills everyday.<sup><a href="http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/#footnote_0_878" id="identifier_0_878" class="footnote-link footnote-identifier-link" title="Admittedly, there are those who don&amp;#8217;t. But I try to keep them far away from my projects. Nothing is more dangerous than a developer who is happy at being stale">1</a></sup> That&#8217;s a heavy toll, but a wonderful one, because you&#8217;re always <em>just about underwater</em>, you&#8217;re always challenged. But, and this is the wonderful part, you&#8217;re always discovering. Every day as a developer is a day that I am doing something that I haven&#8217;t done before. Whether it&#8217;s creating a new architecture, or just improving a workflow. Everyday is about improvement.</p>
<h3>Problems with The Ever-Deployable Git Workflow</h3>
<p>I&#8217;ve been using my <a title="The Ever-Deployable Github Workflow" href="http://mettadore.com/analysis/the-ever-deployable-github-workflow/">Ever-Deployable Git Workflow</a> for a few months now with much success. It&#8217;s been a great way to keep a project up to speed with multiple people working on multiple issues with barely any conflict. Still, nothing is perfect.</p>
<p>One thing I&#8217;ve found is that naming branches is problematic. Few people want to type &#8220;git checkout -b make-javascript-popups-easier-to-maintain,&#8221; it&#8217;s just too long. Also, searching through a long list of issues with names like that just gets troublesome. What is John working on? Oh, something about making Javascript popups better. Well, is that Issue #216? The one about JS file location? Or is it Issue #384?</p>
<p>This brings up two ways that we can make the Ever-Deployable Github workflow better. First, unify with the issue tracker, and second, make better branch names.</p>
<h3>The Github Issue Tracker</h3>
<p>Github&#8217;s issue tracker is probably one of the least functional issue trackers I&#8217;ve ever used. It basically has nothing you&#8217;d expect or want. It&#8217;s little more than a title, some text, and maybe a label.</p>
<p>For that reason, it&#8217;s the best issue tracker I&#8217;ve ever used.</p>
<p>How many of us get sucked into the feature set of a piece of software and end up spending all of our time maintaining the software. Github&#8217;s issue tracker forces us to avoid that tendency by not <em>giving</em> us that feature set. It&#8217;s brilliant. All I can do is write a title, write a description, and then <em>get back to work</em>. It makes logging issues super fast. So recently, I&#8217;ve started to take advantage of that. I log issues for nearly every small, atomic change I want to make.</p>
<p>Furthermore, you can close issues with commit messages like &#8220;Fixes #216 by shuffling the JS files as if they were a deck of cards,&#8221; and the commit then gets linked to the closed issue automagically. It&#8217;s really a great system.</p>
<h3>10 Steps to a Better Workflow</h3>
<p>So, we have a way that we can quickly make issues to log things we want to change. And we want to get rid of insanely long branch names. Why don&#8217;t we branch the issue? This means our branch name is <em>minimally descriptive</em>, but there is as much description as we want in the actual issue. Using this methodology, our new Github Workflow is this:</p>
<ol>
<li>Only work on documented issues. The idea here is that no one is ever just blindly mucking about in the code without a documented reason<sup><a href="http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/#footnote_1_878" id="identifier_1_878" class="footnote-link footnote-identifier-link" title="or at least without creating an issue like &amp;#8220;Issue #516: Blindly mucking about in the code&amp;#8221;">2</a></sup></li>
<li>Look to see if anyone else is working on the issue you are going to start.</li>
<li>Create an issue describing work to be done, or use an existing issue</li>
<li>Create a branch using that issue number. We use &#8220;issueNUM&#8221; as the branch name, so something like &#8220;git checkout -b issue516&#8243;</li>
<li>Immediately, before doing any work, push that branch back to master: &#8220;git push origin issue516.&#8221; This tells everyone that someone is <em>actively working on this issue</em>. This is why you don&#8217;t work on undocumented issues. It&#8217;s very easy to know what the entire team is working on.</li>
<li>Work on your code following The Ever-Deployable Github Workflow. Making commits fairly atomically, or as atomically as your team decides.<sup><a href="http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/#footnote_2_878" id="identifier_2_878" class="footnote-link footnote-identifier-link" title="I like smaller commits, since they are easier to review and revert">3</a></sup></li>
<li>Rebase to master</li>
<li>Commit the branch with a final message like &#8220;Fixes #517 by doing lots of stuff.&#8221;</li>
<li>Push to remote, submit your pull request, and &#8220;git checkout -b &lt;nextIssueNumber&gt;&#8221;</li>
<li>Lather, rinse, and repeat</li>
</ol>
<h3>Fixing other things along the way</h3>
<p>This workflow has done a few things for us. One, it encourages <em>atomic work on the code</em>. By that, I mean it encourages us to stay away from commits that change &#8220;a little of this, little of that.&#8221; We are working on a single issue, and our branch is named with that issue. So we focus on that issue.</p>
<p>If we want to fix other, most often very small, issues during the work, we fix them in a single commit, and log that in the commit message &#8220;Fixes #214 by changing something, since I&#8217;m here already.&#8221; If we want to fix bigger issues, we do it a bit differently.</p>
<p>For instance, say we are working on our issue #516, and during that, we come up with a decent way to correct another issue, say issue #212, that comes up because of our work on this one, but which we don&#8217;t want to dump right into production- maybe we have to test it more:</p>
<pre class="brush: plain; title: ; notranslate">
git checkout -b issue516
git push origin issue516
… do some work and decide to fix issue 212, but not to push it to production without first finishing 516
git checkout -b issue212
git push origin issue212
… fix 212 and commit
git commit -am &quot;Fixes #212 by mucking about in the code&quot;
git push origin issue212
git checkout issue516
… continue working on issue 516
git commit -am &quot;Fixes #516&quot;
… then do the standard git rebase workflow:
git checkout master
git pull origin master
git checkout issue516
git rebase master
… Then submit your pull request for Issue 516. Now, it's a good time to push up 212
git checkout issue212
git rebase issue516
git push origin issue212
</pre>
<p>With this, issue212 is fixed <em>on top of issue516</em> and is ready for either a pull request or more review and work. From a git log perspective, it appears that issue 516 was completed, <em>and then</em> issue 212 was completed. Nice and clean.</p>
<h3>Coda</h3>
<p>I&#8217;ve been using this workflow on various teams for about 2 months now, and it&#8217;s working out extremely well. I&#8217;d be interested in what you think.</p>
<ol class="footnotes"><li id="footnote_0_878" class="footnote">Admittedly, there are those who don&#8217;t. But I try to keep them far away from my projects. Nothing is more dangerous than a developer who is happy at being stale</li><li id="footnote_1_878" class="footnote">or at least without creating an issue like &#8220;Issue #516: Blindly mucking about in the code&#8221;</li><li id="footnote_2_878" class="footnote">I like smaller commits, since they are easier to review and revert</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/the-ever-deployable-github-workflow-part-2-branches-and-issues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[Git Workflow]]></series:name>
	</item>
		<item>
		<title>Hourly work, fairness, and the scamming of lawyers</title>
		<link>http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/</link>
		<comments>http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 23:32:58 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=938</guid>
		<description><![CDATA[I&#8217;ve been working full-time as a contract programmer for a few years now, and have recently begun to realize something very disheartening: My clients get a lot of shit for free. Now, that&#8217;s not disheartening in a &#8220;they get stuff I don&#8217;t get&#8221; sort of way. I mean, good for them. I&#8217;m a happy person [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working full-time as a contract programmer for a few years now, and have recently begun to realize something very disheartening:</p>
<p>My clients get <em>a lot</em> of shit for free.</p>
<p>Now, that&#8217;s not disheartening in a &#8220;they get stuff I don&#8217;t get&#8221; sort of way. I mean, good for them. I&#8217;m a happy person who likes spreading happiness, so I&#8217;m not against them getting shit for free on principle. The problem here is that my clients get a lot of shit for free that <em>I</em> do– and thus, it means that I&#8217;m doing <em>a lot of work for free</em>.</p>
<p>Today is a perfect example of this. Today I did some quick work for a client that submitted a request using my ticketing system. Since I wasn&#8217;t actually working for someone else at the time, I went ahead and tackled it. The time I spent on that, from initially seeing the email to completing it barely scraped 20 minutes. I loosely round to 15 minute increments, and generally don&#8217;t charge for a quick 5-15 minute bit of work. Thus, I did that for free.</p>
<p>Then, since I was already outside of a context, I checked my email, and there was another request. Similar thing, similar outcome. A wee bit of unbilled work.</p>
<p>Then, there was another request from another client. This one took about 45 minutes. So, I went into FreshBooks and went to bill them, only to realize that it was the first time I was billing them this month. I&#8217;ve worked for that client almost 4 times already this month, and this is the first time I&#8217;ve billed them.</p>
<p>I am extremely hesitant at this point to back calculate just how many of these little things I do without billing.</p>
<h3>Metric billing</h3>
<p>When I was working in environmental consulting<sup><a href="http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/#footnote_0_938" id="identifier_0_938" class="footnote-link footnote-identifier-link" title="during my short, foolish attempt to convince myself that I&amp;#8217;m not a developer in my heart">1</a></sup>, I had this ridiculous billing sheet that I had to keep. It was 10ths of an hour, which makes sense from a percentage perspective– easy calculations– but becomes mind-numblingly frustrating when you have to actually write down the fact that you used two billing increments because it took you 10 minutes to go to the bathroom!</p>
<p>I mean, think about that: 10ths of an hour: 6 minute increments. Imagine tracking what you do by looking at every 6 minutes! &#8220;No, I don&#8217;t have time to glance at your stupid Star Wars link, that&#8217;s like 2 whole minutes!!&#8221;</p>
<p>I thought I would go crazy at that job. And yet, oddly, lately I&#8217;ve become to realize that it makes an insane sort of sense. My base rate is $85/hr, which means that one of those billing increments is effectively $8.50, which means that my &#8220;barely scraping 20 minute&#8221; task that I did for my client was worth $25.50.</p>
<p>Again, I am extremely hesitant at this point to back calculate just how many of these little things I do without billing.</p>
<h3>Small clients, hourly work, and the fallacy of &#8216;free&#8217;</h3>
<p>And so we have a problem. I basically refuse to bill more harshly– admittedly out of my own laziness– but continue to have lots of small contracts which, by their very nature, necessitate harsh billing. It makes my relationship with my clients more lopsided, which doesn&#8217;t stay positive. I&#8217;m starting to realize that this is far from a &#8220;good deal&#8221; for my clients. In fact, it&#8217;s a pretty bad thing.</p>
<p>Think about it. I do work for my clients for free, and I do this free work all the time, right? That&#8217;s great because my clients are getting stuff and not paying for it, right? Wrong. The more I do work for free, the more working for this client becomes a burden, either real or perceived, and the worse my work gets. I get less engaged, and more frustrated, with every task.</p>
<p>That&#8217;s not good for either of us. Good business isn&#8217;t about getting shit freely. That&#8217;s a fallacy. Good business is about getting shit fairly.</p>
<h3>I understand the lawyers</h3>
<p>Lawyers. Those bastards.They do this thing which I always thought was really shitty and unfair. They charge you for work they don&#8217;t do. It&#8217;s this scam they have called &#8220;being on retainer.&#8221;<sup><a href="http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/#footnote_1_938" id="identifier_1_938" class="footnote-link footnote-identifier-link" title="Yes, I realize they are not the only ones who use the retainer, but they are my foil for this article, so shut up.">2</a></sup> They charge you this monthly amount for work they &#8220;might&#8221; do. If you call them, you pay. And if you <em>don&#8217;t</em> call them, you pay. Then, if you want them to do <em>a lot</em> of work, you pay more!</p>
<p>I understand this now.</p>
<p>Lawyers aren&#8217;t bastards at all, and they are not scamming at all. It may not be perfect, but what they are doing is trying to get as close as possible to &#8220;fair.&#8221;</p>
<p>This is why my lawyer doesn&#8217;t charge me when I call to ask a simple question, yes. But more importantly, this is why my lawyer <em>is actually engaged</em> when I call to ask that simple question. I now realize why the lawyers do what they do, and I have to say that it&#8217;s a seriously good idea.</p>
<p>I&#8217;ve got a couple clients that I don&#8217;t hear from for months, who will then call with work for me to do. This is a bad situation. Since I&#8217;m not getting paid <em>unless</em> they call me, I have to take on other work, so I fill my schedule, book myself up, then get this call from someone asking me to do work, and I can&#8217;t.</p>
<p>At that point, I have no time for work. It&#8217;s not like I set aside time <em>just in case</em> they called me. I can&#8217;t do that and survive. So we&#8217;re screwed. There&#8217;s no good solution, and anything we come up with is the least crappy choice of either &#8220;fitting it in&#8221; or doing a less than perfect job just to &#8220;get it out of the way&#8221; or even saying &#8220;sorry, you&#8217;re out of luck.&#8221;</p>
<h3>From now on, I&#8217;m on retainer</h3>
<p>Here&#8217;s the thing: I want clients who value their own work, who take their own work seriously– seriously enough that they <em>demand</em> that I take it seriously. Because I take my own work seriously. I spend enormous amounts of time working to improve myself, to work better. I value my work, and I want clients who value me.</p>
<p>I&#8217;m no longer working hourly for any contract that is not a significant portion of my time. My plan is to set a &#8220;retainer rate&#8221; at some fraction of my base rate, which my client will pay monthly in exchange for me <em>guaranteeing</em> that they have a certain amount of hours. Those are hours that I don&#8217;t have to fill with other work. Those are hours I can set aside for my client, and if I don&#8217;t use them for my client, then great, I use them to work anyway, learning another framework, or another language, or just playing with a design pattern, or refactoring something in their code. All of which makes me better, and more valuable to my clients.</p>
<p>It&#8217;s all about value.</p>
<p>Retainer doesn&#8217;t mean &#8220;I&#8217;m charging you for work I might not do.&#8221; Not at all. I see that now. Retainer means &#8220;I have to find work, and you&#8217;re going to get shoved aside and treated like shit, unless I <em>don&#8217;t</em> have to find work.&#8221; Retainer means &#8220;You value your business enough that you don&#8217;t want stuff to &#8216;maybe get fit in.&#8217;&#8221; Retainer guarantees access, but more than that, it guarantees <em>fairness</em>.<sup><a href="http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/#footnote_2_938" id="identifier_2_938" class="footnote-link footnote-identifier-link" title="or, at least, comes as close as we can get easily in our system.">3</a></sup> It says &#8220;I care about my product, and I care about it enough that when I want you to work, I don&#8217;t want to wonder whether you can.&#8221;</p>
<p>It shows that the client values their product, it certainly shows that the client values me, but most of all it shows that I&#8217;d damn-well better value this client.</p>
<p>That, my friend, is good business.</p>
<ol class="footnotes"><li id="footnote_0_938" class="footnote">during my short, foolish attempt to convince myself that I&#8217;m not a developer in my heart</li><li id="footnote_1_938" class="footnote">Yes, I realize they are not the only ones who use the retainer, but they are my foil for this article, so shut up.</li><li id="footnote_2_938" class="footnote">or, at least, comes as close as we can get easily in our system.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/hourly-work-fairness-and-the-scamming-of-lawyers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t be an idiot like me, mock your services!</title>
		<link>http://mettadore.com/analysis/dont-be-an-idiot-like-me-mock-your-services/</link>
		<comments>http://mettadore.com/analysis/dont-be-an-idiot-like-me-mock-your-services/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 19:02:28 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://mettadore.com/?p=930</guid>
		<description><![CDATA[You know the old saying, a derivative of: &#8220;Test are like flossing, we all know we should write them, but no-one does.&#8221; That&#8217;s an old saying because, while it was true 10-20 years ago, it&#8217;s not so true now. For the most part, the modern development world is a beautifully tested one. These days, nearly [...]]]></description>
			<content:encoded><![CDATA[<p>You know the old saying, a derivative of: &#8220;Test are like flossing, we all know we should write them, but no-one does.&#8221; That&#8217;s an old saying because, while it was true 10-20 years ago, it&#8217;s not so true now. For the most part, the modern development world is a beautifully tested one. These days, nearly everyone flosses.</p>
<p>Still, there are always improvements. Sure, we test, but maybe we don&#8217;t really test the web interactions, or test the controllers as well as we should, or whatever. We&#8217;re flossing, but we&#8217;re not really flossing as well as we could be. We&#8217;re missing some teeth.</p>
<p>Today, I got a toothache.</p>
<h3>Mock your services</h3>
<p>My company, Hydrasi, has what is a fairly common architecture these days. We have a front-end website (in Rails) that sessions users and does various pretty things, and we have various back-end servers (our main is in Scala) that do things like manage data, send messages, etc. Everything connects to everything else via messaging and API calls. This is basic &#8220;concern separated&#8221; design. The Rails site shouldn&#8217;t care what the hell happens in the Scala server, it should just care that when it says &#8220;give me a monkey,&#8221; it get&#8217;s a monkey. It&#8217;s a nice separation because I &#8220;own&#8221; the front end, and my partner &#8220;owns&#8221; the back end.</p>
<p>And yet, with all of this architectural decision making and best practices, today I&#8217;m at a work-stoppage point because my front-end tests are failing. Why? Because I&#8217;m an idiot and built them all while I had a back-end server that was functional. Today, that service is *not* functional, and my partner is out, probably doing what he should be doing on a Saturday– having fun.</p>
<p>Yes, I feel really stupid. I spent an hour trying to hack around and get the back-end services running so I could work.</p>
<p>Yes, I already feel stupid, and yes, it&#8217;s obvious that I haven&#8217;t really been flossing.</p>
<p>So now, instead of working on what I thought I was going to work on, I&#8217;m heading over to grab the <a href="http://fakeweb.rubyforge.org/">FakeWeb </a>gem so that <em>next</em> time I work, it won&#8217;t matter whether any other servers are running.</p>
<p>(in a month, I&#8217;ll write a post about how I forgot to write integration tests <img src='http://mettadore.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://mettadore.com/analysis/dont-be-an-idiot-like-me-mock-your-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

