<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>Articles by thoughtbot about design, Ruby on Rails, and iOS.</description><title>giant robots smashing into other giant robots</title><generator>Tumblr (3.0; @thoughtbot)</generator><link>http://robots.thoughtbot.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GiantRobotsSmashingIntoOtherGiantRobots" /><feedburner:info uri="giantrobotssmashingintoothergiantrobots" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><feedburner:emailServiceId>GiantRobotsSmashingIntoOtherGiantRobots</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item><title>How to write a great README</title><description>&lt;p&gt;Leadership is often defined as having the ability to make others want to do what it is that you would like them to do. You want people to want to use your software, and often their first introduction will be through the README in the source code or on the project&amp;#8217;s GitHub page.&lt;/p&gt;

&lt;h2 id="the_basics"&gt;The Basics&lt;/h2&gt;

&lt;p&gt;There are of course components to a technical document that make it more effective. Describe what it is that your project makes easier. Provide code examples detailing how the use of the library. Document the installation process. These are the basic elements which define a README.&lt;/p&gt;

&lt;p&gt;Creating a great face for your project, however, requires still more.&lt;/p&gt;

&lt;h2 id="dont_get_lazy_just_because_this_is_for_developers"&gt;Don’t get lazy just because this is for developers&lt;/h2&gt;

&lt;p&gt;Technical writing is still writing, and need not be dry and boring. Just as if you were writing an essay or blog post, you should strive to grab the attention of your reader early. This can be easily accomplished with a &lt;a href="http://writingcommons.org/process/organize/paper-structure/396-how-to-write-an-engaging-introduction"&gt;well-written introductory paragraph&lt;/a&gt;. Use strong or emphasised text to give a short description of what the software does, such as &lt;strong&gt;“&lt;a href="https://github.com/thoughtbot/griddler"&gt;Receive emails in your Rails app&lt;/a&gt;”&lt;/strong&gt;. You can also use an image which relates to the &lt;a href="https://github.com/play/play#background"&gt;functionality of your library&lt;/a&gt; or alludes to some pun in the name.&lt;/p&gt;

&lt;p&gt;Your readers will most likey view your README in a browser. Please keep that in mind when formatting its content. Put the name of the library in an &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; at the beginning of the file. Categorize content using two or three levels of header beneath. Make use of emphasis to call out important words. Link to project pages for related libraries you mention. Link to Wikipedia, Wiktionary, even Urban Dictionary definitions for words of which a reader may not be familiar. Make amusing cultural references. Add links to related projects or services.&lt;/p&gt;

&lt;h2 id="the_code_matters"&gt;The code matters&lt;/h2&gt;

&lt;p&gt;Besides speaking English, your readers also understand code. Developers love to see code samples, and a few lines of &lt;em&gt;syntax highlighted&lt;/em&gt; source are worth a thousand words. &lt;a href="https://github.com/plataformatec/simple_form"&gt;&lt;code&gt;plataformatec/simple_form&lt;/code&gt;&lt;/a&gt; does an excellent job of providing code examples as well as explanations for nearly every setting and interface call. Besides being extremely &lt;a href="http://en.wiktionary.org/wiki/greppable"&gt;greppable&lt;/a&gt;, &lt;code&gt;simple_form&lt;/code&gt;’s README is the top Google hit for nearly all &lt;code&gt;simple_form&lt;/code&gt; searches.&lt;/p&gt;

&lt;p&gt;Be aware that sometimes the reason someone is visiting your project’s page is that they have a problem. If you know about persistent issues, such as resolving a functional dependency, call that out in a section of its own and provide a solution or workaround. Right in the README. Yeah. A great example of one such issue is &lt;a href="https://github.com/thoughtbot/capybara-webkit"&gt;&lt;code&gt;thoughtbot/capybara-webkit&lt;/code&gt;&lt;/a&gt;’s dependency upon &lt;code&gt;Qt&lt;/code&gt;. Because a gem cannot satisfy this dependency, we &lt;a href="https://github.com/thoughtbot/capybara-webkit#qt-dependency-and-installation-issues"&gt;added a notice&lt;/a&gt; about installation issues to the README.&lt;/p&gt;

&lt;p&gt;You are also encouraged to add “badges,” such as &lt;a href="http://travis-ci.org"&gt;Travis CI&lt;/a&gt;’s &lt;img src="http://media.tumblr.com/6df8b0d6154a26601b9a3ef1c9662de7/tumblr_inline_mn2e2keoSG1qz4rgp.png" style="margin-bottom: 0;" alt="image"/&gt; or &lt;a href="http://codeclimate.com"&gt;Code Climate&lt;/a&gt;’s &lt;img src="http://media.tumblr.com/7e8748c62e5e2d21e298b865424c2e77/tumblr_inline_mn2e2wmbOH1qz4rgp.png" style="margin-bottom: 0;" alt="image"/&gt; to your README, but remember that they reflect on your project—a passing build with high quality code attracts developers to your library, while a failing master build can give them pause.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://plus.google.com/111599109936753790268"&gt;Caleb Thompson&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/4keVnDMCTnY/50852570430</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50852570430</guid><pubDate>Sun, 19 May 2013 17:27:00 -0400</pubDate><category>writing</category><category>readme</category><category>open source</category><feedburner:origLink>http://robots.thoughtbot.com/post/50852570430</feedburner:origLink></item><item><title>Sandi Metz’ rules for developers</title><description>&lt;p&gt;Back in January, &lt;a href="http://sandimetz.com"&gt;Sandi Metz&lt;/a&gt; introduced her rules for developers in a &lt;a href="http://rubyrogues.com/087-rr-book-clubpractical-object-oriented-design-in-ruby-with-sandi-metz/"&gt;Ruby Rogues podcast episode&lt;/a&gt; episode. Around the time Sandi’s rules were published, the team I am on was starting a new project. This post details the experience of that team applying Sandi’s rules to the new application.&lt;/p&gt;

&lt;h2&gt;The rules&lt;/h2&gt;
&lt;br/&gt;&lt;figure style="margin-left: auto; margin-right: auto; width: 570px;"&gt;&lt;a href="http://www.youtube.com/watch?v=o_eSwq1ewsU"&gt;&lt;img src="http://f.cl.ly/items/0c0I2M012Z453C1k243z/four%20lights.png" alt="There are four lights."/&gt;&lt;/a&gt;
  &lt;figcaption style="text-align: center"&gt;&lt;em&gt;There are four rules.&lt;/em&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Here are the rules:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Classes can be no longer than one hundred lines of code.&lt;/li&gt;
&lt;li&gt;Methods can be no longer than five lines of code.&lt;/li&gt;
&lt;li&gt;Pass no more than four parameters into a method. Hash options are parameters.&lt;/li&gt;
&lt;li&gt;Controllers can instantiate only one object. Therefore, views can only know about one instance variable and views should only send messages to that object
(&lt;code&gt;@object.collaborator.value&lt;/code&gt; is not allowed).&lt;/li&gt;
&lt;/ol&gt;&lt;h2&gt;When to break these rules&lt;/h2&gt;

&lt;p&gt;Paraphrasing Sandi, “You should break these rules only if you have a good reason or your pair lets you.” Your pair or the person &lt;a href="https://github.com/thoughtbot/guides/tree/master/code-review"&gt;reviewing your code&lt;/a&gt; are the people who you should ask.&lt;/p&gt;

&lt;p&gt;Think of this as rule zero. It is immutable.&lt;/p&gt;

&lt;h2&gt;100-line classes&lt;/h2&gt;

&lt;p&gt;Despite the large number of private methods we wrote, keeping classes short proved easy. It forced us consider what the &lt;a href="http://c2.com/cgi/wiki?SingleResponsibilityPrinciple"&gt;single responsibility&lt;/a&gt; of our class was, and what should be extracted.&lt;/p&gt;

&lt;p&gt;This applied to specs as well. In one case, we found a spec file ran over the limit which helped us realize we were testing too many features. We split the file into a few, more focused, feature specs.&lt;/p&gt;

&lt;p&gt;That made us realize that &lt;code&gt;git diff&lt;/code&gt;s wouldn’t necessarily show us when we exceed 100 lines.&lt;/p&gt;

&lt;h2&gt;Five lines per method&lt;/h2&gt;

&lt;p&gt;Limiting methods to five lines per method is the most interesting rule.&lt;/p&gt;

&lt;p&gt;We agreed &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, and &lt;code&gt;end&lt;/code&gt; are all lines. In an &lt;code&gt;if&lt;/code&gt; block with two branches, each branch could only be one line.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def validate_actor
  if actor_type == 'Group'
    user_must_belong_to_group
  elsif actor_type == 'User'
    user_must_be_the_same_as_actor
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Five lines ensured that we never use &lt;code&gt;else&lt;/code&gt; with &lt;code&gt;elsif&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Having only one line per branch urged us to use well-named private methods to get work done. Private methods are great documentation. They need very clear names, which forced us to think about the content of the code we were extracting.&lt;/p&gt;

&lt;h2&gt;Four method arguments&lt;/h2&gt;

&lt;p&gt;The four method arguments rule was particularly challenging in Rails, and particularly in the views.&lt;/p&gt;

&lt;p&gt;View helpers such as &lt;code&gt;link_to&lt;/code&gt; or &lt;code&gt;form_for&lt;/code&gt; can end up requiring many parameters to work correctly. While we put some effort into not passing too many arguments, we fell back to Rule 0 and left the parameters if we couldn’t find a better way to do it.&lt;/p&gt;

&lt;h2&gt;Only instantiate one object in the controller&lt;/h2&gt;

&lt;p&gt;This rule raised the most eyebrows before we started the experiment. Often, we needed more than one type of thing on a page. For example, a homepage needed both an activity feed and a notification counter.&lt;/p&gt;

&lt;p&gt;We solved this using the &lt;a href="http://c2.com/cgi/wiki?FacadePattern"&gt;Facade Pattern&lt;/a&gt;. It looked like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/facades/dashboard.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Dashboard
  def initialize(user)
    @user = user
  end

  def new_status
    @new_status ||= Status.new
  end

  def statuses
    Status.for(user)
  end

  def notifications
    @notifications ||= user.notifications
  end

  private

  attr_reader :user
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;app/controllers/dashboards_controller.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class DashboardsController &amp;lt; ApplicationController
  before_filter :authorize

  def show
    @dashboard = Dashboard.new(current_user)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;app/views/dashboards/show.html.erb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= render 'profile' %&amp;gt;
&amp;lt;%= render 'groups', groups: @dashboard.group %&amp;gt;

&amp;lt;%= render 'statuses/form', status: @dashboard.new_status %&amp;gt;
&amp;lt;%= render 'statuses', statuses: @dashboard.statuses %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;Dashboard&lt;/code&gt; class provided a common interface for locating the user’s collaborator objects and we passed the dashboard’s state to view partials.&lt;/p&gt;

&lt;p&gt;We didn’t count instance variables in controller memoizations toward the limit. We used a convention of prefixing unused variables with an underscore to make it clear what is meant to be used in a view:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def calculate
  @_result_of_expensive_calculation ||= SuperCalculator.get_started(thing)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Great success!&lt;/h2&gt;

&lt;p&gt;We recently concluded our experiment as a success, published results in &lt;a href="http://tinyletter.com/thoughtbot/letters/the-bot-cave-march-2013"&gt;our research newsletter&lt;/a&gt;, and have incorporated the rules into our &lt;a href="https://github.com/thoughtbot/guides/tree/master/best-practices"&gt;best practices guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://plus.google.com/111599109936753790268"&gt;Caleb Thompson&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Y4q3tSFhQnE/50655960596</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50655960596</guid><pubDate>Fri, 17 May 2013 11:30:00 -0400</pubDate><category>ruby</category><category>rails</category><category>guidelines</category><feedburner:origLink>http://robots.thoughtbot.com/post/50655960596</feedburner:origLink></item><item><title>Google Hangout for Standups and Interviews</title><description>&lt;p&gt;We&amp;#8217;ve been experimenting with &lt;a href="http://www.google.com/+/learnmore/hangouts/"&gt;Google Hangout&lt;/a&gt; for meetings such as &lt;a href="http://playbook.thoughtbot.com/finding-a-rhythm/daily-standups/"&gt;daily standups&lt;/a&gt; with remote team members and interviews with remote candidates.&lt;/p&gt;

&lt;p&gt;We concluded this experiment was a success.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s nice to have a recurring calendar invite to open, click &amp;#8220;Join Hangout&amp;#8221; and start talking.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/5a1445c0db282448ce45b85dbcdd586a/tumblr_inline_mmlj0q4Poq1qz4rgp.png" alt="Calendar invite"/&gt;&lt;/p&gt;

&lt;p&gt;Google Hangout is sometimes choppy over wifi. The settings need to change when we switch from laptop to monitor, so we often are without sound for a few seconds before changing the &amp;#8220;FaceTime Camera (Built-In)&amp;#8221; setting to &amp;#8220;FaceTime HD Camera (Display)&amp;#8221;.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/69bbbcf7cca861749b493853a2060b0d/tumblr_inline_mmqwe8Dukt1qz4rgp.png" alt="face"/&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve noticed in longer meetings, we sometimes need to refresh the page if sound starts to get choppy, presumably to clear some buffering.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve noticed during Hangouts that the sound captured by a Macbook Air&amp;#8217;s internal microphones is often muffled. We generally have Macbook Pros for better performance of test suites, but there are a few of us who have Airs. We have started to fall back to phone calls for sound in those cases.&lt;/p&gt;

&lt;p&gt;Overall, it&amp;#8217;s always better to see someone&amp;#8217;s face.&lt;/p&gt;

&lt;p&gt;Written by &lt;a rel="author" href="https://profiles.google.com/115463449660844194795"&gt;Dan Croak&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Lub-1xx5x5E/50418471394</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50418471394</guid><pubDate>Tue, 14 May 2013 09:30:15 -0400</pubDate><category>process</category><category>teamwork</category><feedburner:origLink>http://robots.thoughtbot.com/post/50418471394</feedburner:origLink></item><item><title>Episode 48: Barista imposter syndrome</title><description>&lt;a href="http://learn.thoughtbot.com/podcast/48"&gt;Episode 48: Barista imposter syndrome&lt;/a&gt;: &lt;p&gt;In this episode, recorded at RailsConf 2013, Ben Orenstein is joined by Jon Larkowski, closet hippie and developer at CareZone. Ben and Jon discuss being a closet hippie, transitioning from consulting to working on a startup/product team, ping-pong, paying attention to your habits and improving to your life, meditation, firewalling your attention, fostering a startup culture, imposter syndrome, podcasting, coffee, code review, guitar, and much more.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/48"&gt;Episode Notes and Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://itunes.apple.com/us/podcast/giant-robots-smashing-into/id535121941"&gt;Subscribe via iTunes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast.xml"&gt;Subscribe via RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/48.mp3"&gt;Direct Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/zo0YSeiDFWU/50341444095</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50341444095</guid><pubDate>Mon, 13 May 2013 10:00:02 -0400</pubDate><category>Ruby on Rails</category><category>software development</category><feedburner:origLink>http://robots.thoughtbot.com/post/50341444095</feedburner:origLink></item><item><title>Ruby Science: You down with OCP?</title><description>&lt;p&gt;Yeah, you know me.&lt;/p&gt;

&lt;p&gt;We just pushed the latest update to &lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newchapters"&gt;Ruby Science&lt;/a&gt;, including five new chapters. Previous purchasers and &lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=prime"&gt;Prime&lt;/a&gt; subscribers can grab the update &lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newchapters"&gt;on Learn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;New chapters this week discuss:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Using the Single Responsibility Principle to create readable, reusable
classes.&lt;/li&gt;
&lt;li&gt;Applying the Open/Closed Principle to reduce churn and prevent breakage while
keeping objects easy to change.&lt;/li&gt;
&lt;li&gt;Applying the Dependency Inversion Principle to create flexible, reusable
objects.&lt;/li&gt;
&lt;li&gt;Using the Law of Demeter to prevent application dependencies from becoming a
tangled mess.&lt;/li&gt;
&lt;li&gt;Choosing Composition Over Inheritance to make simpler, more flexible software.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The book is a work in progress, and is currently 230 pages long. Your purchase gets you access to the current release of the book, all future updates, and the companion example application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newchapters"&gt;Get your copy of Ruby Science today&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Now Available For Free With Learn Prime&lt;/h2&gt;

&lt;p&gt;We recently launched a service to help subscribers become better developers, called &lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newchapters"&gt;Learn Prime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For just $99/month, you get ongoing access to everything we teach, including books like Ruby Science. You&amp;#8217;ll even get access to all our in-person and online workshops. Get access to exclusive subscriber content and use the forum to ask thoughtbot your toughest Ruby, Rails, and refactoring questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newchapters"&gt;Subscribe now&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by &lt;a rel="author" href="https://profiles.google.com/117498214118571395381"&gt;Joe Ferris&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/j52SXnlwA1g/50098519739</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50098519739</guid><pubDate>Fri, 10 May 2013 13:24:00 -0400</pubDate><category>ruby</category><category>ruby science</category><feedburner:origLink>http://robots.thoughtbot.com/post/50098519739</feedburner:origLink></item><item><title>Reducing Churn in Subscription Services</title><description>&lt;p&gt;You&amp;#8217;ve probably heard by now that we&amp;#8217;ve launched a learning community for passionate Rails developers called &lt;a href="http://learn.thoughtbot.com/?utm_source=giant-robots&amp;amp;utm_medium=blog-post&amp;amp;utm_campaign=brennan-dunn-churn-interview"&gt;Prime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since Prime is a subscription service, one of metrics we&amp;#8217;re interested in is churn, defined as the percentage of total customers who cancel. Over the last 30 days, Prime&amp;#8217;s churn has been 18%.&lt;/p&gt; 

&lt;p&gt;Estimates of what a &amp;#8220;good&amp;#8221; churn is vary. One broad survey of SaaS companies with less than $10M in revenues showed a median churn of 20%, while some blog posts insist that anything over 8% should be panic-inducing.&lt;/p&gt;

&lt;p&gt;To gain some perspective and get advice, I reached out to a friend and &lt;a href="http://learn.thoughtbot.com/podcast/18"&gt;former podcast guest&lt;/a&gt;, &lt;a href="http://brennandunn.com/"&gt;Brennan Dunn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Brennan is creator of a successful SaaS app called &lt;a href="http://planscope.io"&gt;Planscope&lt;/a&gt;, author of several &lt;a href="http://brennandunn.com/products/"&gt;excellent ebooks&lt;/a&gt;, and overall &amp;#8220;good at making money on the internet&amp;#8221; kind of guy.&lt;/p&gt;

&lt;p&gt;Below, you&amp;#8217;ll find a recording of our 40-minute chat. In it, we dig into Prime&amp;#8217;s current stats (including subscriber count and revenue growth), and Brennan&amp;#8217;s suggestions for how to improve the site. What started off as recommendations for reducing churn turned into a broader discussion of how to position the entire service. If you run a subscription service of your own, you&amp;#8217;ll likely learn a thing or two from Brennan&amp;#8217;s battle-tested advice.&lt;/p&gt; 

&lt;p&gt;Check it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://thoughtbot-blog.s3.amazonaws.com/brennan-dunn.mp3"&gt;Direct download&lt;/a&gt;.&lt;/p&gt;

&lt;div&gt;
  
    
  
&lt;/div&gt;

&lt;p&gt;If our discussion left you with further questions for Brennan, leave them in the comments below and perhaps we can convince him to respond.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/k90cEeFtAyk/50087515419</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50087515419</guid><pubDate>Fri, 10 May 2013 09:30:29 -0400</pubDate><category>prime</category><category>sass</category><category>churn</category><feedburner:origLink>http://robots.thoughtbot.com/post/50087515419</feedburner:origLink></item><item><title>New screencast: Improving Performance for Real-time Requests</title><description>&lt;p&gt;We&amp;#8217;re pleased to announce our newest screencast video on Learn, &lt;a href="https://learn.thoughtbot.com/products/16-improving-performance?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=performance"&gt;Improving Performance for Real-time Requests&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This video, with thoughtbot CTO Joe Ferris, shows you how to tune performance using a real world example.  Starting with an action that takes 3 seconds to respond and performs over 1600 database queries, Joe is able to reduce response time to 300ms and drop database usage to just 5 queries.&lt;/p&gt;

&lt;p&gt;This video specifically focuses on what Joe calls ‘real-time requests’. That is, requests that must return all of their data to the user in the request-response cycle, without relying on background jobs or persistent caching.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="http://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=performance"&gt;Prime&lt;/a&gt; subscribers get this new video included with their monthly subscription. You can also purchase it individually for $15 or for your whole company for just $49.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Slow Rails applications annoy users and lead to lost revenue. Achieve a competitive advantage by making your application UNCOMFORTABLY FAST. &lt;a href="https://learn.thoughtbot.com/products/16-improving-performance?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=performance"&gt;Learn how today!&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/gWw8SksvFTA/50024515543</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/50024515543</guid><pubDate>Thu, 09 May 2013 14:12:16 -0400</pubDate><category>performance</category><category>ruby on rails</category><feedburner:origLink>http://robots.thoughtbot.com/post/50024515543</feedburner:origLink></item><item><title>Announcing Learn for iPad</title><description>&lt;p&gt;&lt;span&gt;&lt;img alt="image" src="http://media.tumblr.com/198b1b00eeb9bdcb7d7f9fbb50aa61f5/tumblr_inline_mmi287gbU41qz4rgp.png"/&gt;&lt;img alt="image" src="http://media.tumblr.com/06104bde2fa0a66bf08ced56f70ff694/tumblr_inline_mmi28dshKh1qz4rgp.png"/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Today we released a new version of Learn to the App Store, &lt;/span&gt;&lt;span&gt;which adds the most frequently requested feature, iPad support!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Additionally, this release includes several improvements &lt;/span&gt;&lt;span&gt;on both &lt;/span&gt;&lt;span&gt;iPhone and iPad. Resources that are available as iBooks can now be &lt;/span&gt;&lt;span&gt;viewed in the iBookstore, better navigation controls have been added &lt;/span&gt;&lt;span&gt;to web resources, and check-offs are now accompanied by sweet audio &lt;/span&gt;&lt;span&gt;feedback.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you would like to add resources to the Trail Map that the app &lt;/span&gt;&lt;span&gt;uses, please contribute to the &lt;/span&gt;&lt;a href="http://github.com/thoughtbot/trail-map"&gt;open source repository on GitHub.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Learn is available for &lt;/span&gt;&lt;a href="https://itunes.apple.com/us/app/thoughtbot-learn/id605401428?mt=8"&gt;free on the App Store&lt;/a&gt;&lt;span&gt;, so try it out today!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Written by &lt;a href="https://profiles.google.com/108603415953993074314" rel="author"&gt;Diana Zmuda&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/OSLbhG91eb0/49968651277</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49968651277</guid><pubDate>Wed, 08 May 2013 19:30:00 -0400</pubDate><category>ios</category><category>learn</category><category>iPad</category><feedburner:origLink>http://robots.thoughtbot.com/post/49968651277</feedburner:origLink></item><item><title>Episode 47: Two hours per minute</title><description>&lt;a href="http://learn.thoughtbot.com/podcast/47"&gt;Episode 47: Two hours per minute&lt;/a&gt;: &lt;p&gt;In this episode, recorded at RailsConf 2013, Ben Orenstein is joined by Ryan Bates of RailsCasts. Ben and Ryan discuss Ryan’s transition to working on RailsCasts full time, staying up to date on the latest technology, how his coding style has changed, maintaining his open source, the process of producing RailsCasts, why he doesn’t speak at conferences, the latest technology he is excited about, and much more&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/47"&gt;Episode Notes and Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://itunes.apple.com/us/podcast/giant-robots-smashing-into/id535121941"&gt;Subscribe via iTunes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast.xml"&gt;Subscribe via RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/47.mp3"&gt;Direct Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/EFcp5SiiXLw/49774041428</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49774041428</guid><pubDate>Mon, 06 May 2013 10:00:19 -0400</pubDate><category>ruby on rails</category><category>screencast</category><category>Business</category><category>open source</category><feedburner:origLink>http://robots.thoughtbot.com/post/49774041428</feedburner:origLink></item><item><title>Strong parameters as documentation</title><description>&lt;p&gt;Besides moving attribute whitelisting to the controller rather than the model,
&lt;a href="http://weblog.rubyonrails.org/2012/3/21/strong-parameters/"&gt;Rails 4’s move to
Strong Parameters&lt;/a&gt;
over &lt;code&gt;attr_accessible&lt;/code&gt; provides great documentation about the data with which
records are being created.&lt;/p&gt;

&lt;p&gt;&lt;figure&gt;
    &lt;img src="http://i3.ytimg.com/vi/jG2KMkQLZmI/hqdefault.jpg" alt="Your music is bad and you should feel bad"/&gt;
    &lt;figcaption&gt;strong_parameters are good and you should feel good&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of a controller many of us have written, using
&lt;code&gt;strong_parameters&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CommentsController &amp;amp;lt; ApplicationController
  respond_to :html

  def create
    @comment = Comment.create(comment_params)
    respond_with @comment
  end

  private

  def comment_params
    params.
      require(:comment).
      permit(:body).
      merge(user: current_user, commentable: commentable)
  end

  def commentable
    # find and return a commentable record
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice how the &lt;code&gt;comment_params&lt;/code&gt; method tells you at a glance what object’s
parameters this controller/action cares about (&lt;code&gt;comment&lt;/code&gt;), the specific data
being used (&lt;code&gt;body&lt;/code&gt;), and the extra information being added. After glancing at
the method, you hardly have to concern yourself with the rest of the class:
everything just makes sense.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;strong_parameters&lt;/code&gt; will be standard in Rails 4.0, but they can be &lt;a href="https://github.com/rails/strong_parameters#installation"&gt;used now in
Rails 3.*&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://plus.google.com/111599109936753790268"&gt;Caleb Thompson&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/KVlldeRmeG8/49374573556</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49374573556</guid><pubDate>Wed, 01 May 2013 14:56:00 -0400</pubDate><category>strong_parameters</category><category>ruby</category><category>rails</category><category>documentation</category><feedburner:origLink>http://robots.thoughtbot.com/post/49374573556</feedburner:origLink></item><item><title>We're at RailsConf 2013!</title><description>&lt;p&gt;Winter is finally over, spring is here, and thoughtbot folks have flown in from Boston, San Francisco, Stockholm, and Boulder to be at &lt;a href="http://www.railsconf.com/2013"&gt;RailsConf 2013&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Do you have any questions about &lt;a href="http://www.thoughtbot.com/community"&gt;our open source projects&lt;/a&gt;? Do you need some help setting up your project on &lt;a href="https://www.apptrajectory.com/"&gt;Trajectory&lt;/a&gt;, or do you want to &lt;a href="https://learn.thoughtbot.com"&gt;Learn&lt;/a&gt; something? We would love to chat with you!&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re also setting up a temporary studio for our &lt;a href="http://learn.thoughtbot.com/podcast"&gt;podcast&lt;/a&gt; in room D136. Feel free to stop by to say hi and watch us record live!&lt;/p&gt;

&lt;p&gt;Adarsh Pandit, Ben Orenstein, George Brocklehurst, Harlow Ward, and Prem Sichanugrist are giving talks:&lt;/p&gt;

&lt;p&gt;Tuesday at 11:30am: &lt;a href="http://www.railsconf.com/2013/talks#talk-64"&gt;TDD Workshop: Outward-in Development, Unit Tests, and Fixture Data&lt;/a&gt;&lt;br/&gt;
Tuesday at 12:20pm: &lt;a href="http://www.railsconf.com/2013/talks#talk-64"&gt;TDD Workshop: Mocking, Stubbing, and Faking External Services&lt;/a&gt; with &lt;a href="https://twitter.com/hrward"&gt;Harlow Ward&lt;/a&gt; and &lt;a href="https://twitter.com/adarshp"&gt;Adarsh Pandit&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;thoughtbot are creators of the open-sourced testing tools FactoryGirl and Shoulda Matchers.&lt;/p&gt;
  
  &lt;p&gt;We recognize Test-Driven Development (TDD) can be difficult to practice as features increase in complexity. Testing is often skipped when developers feel uncomfortable with TDD or have not yet seen certain approaches in practice.&lt;/p&gt;
  
  &lt;p&gt;We’ll describe specific techniques used in TDD which touch on: Integration testing with RSpec+Capybara, Model Associations and Data Validations, Asynchronous Jobs, Emails, 3rd Party Services, and JSON API endpoints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tuesday at 2:00pm: &lt;a href="http://www.railsconf.com/2013/talks#talk-29"&gt;Sleeping with the enemy&lt;/a&gt; with &lt;a href="https://twitter.com/georgebrock"&gt;George Brocklehurst&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In this session we&amp;#8217;ll go off the Rails and take a look at what our Pythonista cousins are doing with Django.&lt;/p&gt;
  
  &lt;p&gt;I&amp;#8217;ll start with some live coding: recreating DHH&amp;#8217;s infamous 15 minute blog demo using Django and explaining the building blocks of a Django app along the way. I&amp;#8217;ll then take that app and use it to look at some design decisions Django makes, and how they compare to Rails. You&amp;#8217;ll see convention over configuration in places you didn&amp;#8217;t expect it, why Django doesn&amp;#8217;t need attr_accessible or strong parameters, and how the template method pattern could change your life.&lt;/p&gt;
  
  &lt;p&gt;Why talk about Python at a Rails conference? Seeing another way of doing things forces us to think about what we&amp;#8217;re doing, challenges or validates the assumptions we make about our work, and inspires us to try new things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wednesday at 2:00pm: &lt;a href="http://www.railsconf.com/2013/talks#talk-44"&gt;Zero-downtime payment platforms&lt;/a&gt; with &lt;a href="https://twitter.com/sikachu"&gt;Prem Sichanugrist&lt;/a&gt; and &lt;a href="https://twitter.com/rtwomey"&gt;Ryan Twomey&lt;/a&gt; (from &lt;a href="https://www.thelevelup.com"&gt;LevelUp&lt;/a&gt;):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When you&amp;#8217;re building a payment platform, you want to make sure that your system is always available to accept orders. However, the complexity of the platform introduces the potential for it to go down when any one of the moving parts fails. In this talk, I will show you the approaches that we&amp;#8217;ve taken and the risks that we have to take to ensure that our platform will always be available for our customers. Even if you&amp;#8217;re not building a payment platform, these approaches can be applied to ensure a high availability for your platform or service as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thursday at 10:30am: &lt;a href="http://www.railsconf.com/2013/talks#talk-36"&gt;How to Talk to Developers&lt;/a&gt; with &lt;a href="https://twitter.com/r00k"&gt;Ben Orenstein&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nearly every developer will be asked to present to his or her peers at some point. Those that do it well will tend to have an outsized influence on their team, company, and community.&lt;/p&gt;
  
  &lt;p&gt;This talk will demonstrate (mostly by example) the straightforward techniques for giving excellent presentations, from a veteran conference speaker and teacher.
  Topics to cover include:&lt;/p&gt;
  
  &lt;ul&gt;&lt;li&gt;Phrases that turn your audience against you.  &lt;/li&gt;
  &lt;li&gt;Basic body language tips that affect perception.  &lt;/li&gt;
  &lt;li&gt;How to be more interesting than the internet.  &lt;/li&gt;
  &lt;li&gt;The power of live coding and demos.  &lt;/li&gt;
  &lt;li&gt;Being funny without resorting to reddit memes.  &lt;/li&gt;
  &lt;li&gt;How to get plenty of questions during Q&amp;amp;A.  &lt;/li&gt;
  &lt;li&gt;How to get an unfair amount of talk acceptances (aka &amp;#8216;Bribing conference organizers&amp;#8217;).&lt;/li&gt;
  &lt;/ul&gt;&lt;/blockquote&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/-sy3KPTdWQA/49241219809</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49241219809</guid><pubDate>Tue, 30 Apr 2013 01:19:00 -0400</pubDate><category>ruby on rails</category><category>conference</category><category>railsconf</category><feedburner:origLink>http://robots.thoughtbot.com/post/49241219809</feedburner:origLink></item><item><title>Episode 46: We don't have a monopoly on being unhealthy</title><description>&lt;a href="http://learn.thoughtbot.com/podcast/46"&gt;Episode 46: We don't have a monopoly on being unhealthy&lt;/a&gt;: &lt;p&gt;Ben Orenstein is joined by Joe Kutner, programmer and author of ‘The Healthy Programmer’. Ben and Joe discuss how the demands of a development job lead to unhealthy habits, and ways to address the issues. They discuss specifics like standing desks, walking desks, the pomodoro technique, exercise, vitamin D, and much more.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/46"&gt;Episode Notes and Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://itunes.apple.com/us/podcast/giant-robots-smashing-into/id535121941"&gt;Subscribe via iTunes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast.xml"&gt;Subscribe via RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/46.mp3"&gt;Direct Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Zhz9loleGaU/49177869240</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49177869240</guid><pubDate>Mon, 29 Apr 2013 10:00:30 -0400</pubDate><category>programming</category><category>healthy</category><feedburner:origLink>http://robots.thoughtbot.com/post/49177869240</feedburner:origLink></item><item><title>It's for the orphans!</title><description>&lt;p&gt;Too often, I come across GitHub Pages branches (&lt;code&gt;gh-pages&lt;/code&gt;) branches that are simply forks from the &lt;code&gt;master&lt;/code&gt; branch of the repository. This is not ideal.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/2Y2F0o1R1x0s122y4139/Commit%20History%20%C2%B7%20thoughtbot_bourbon-2.jpg" alt="Commit History showing Merge master into gh-pages on GitHub"/&gt;&lt;/p&gt;

&lt;p&gt;There are several problems with this strategy:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Unless you manually update the &lt;code&gt;gh-pages&lt;/code&gt; branch every time you add a commit to master, you will be out of date.&lt;/li&gt;
&lt;li&gt;It makes for a much more difficult to understand source folder for the jekyll or HTML site, since people have to mentally categorize every file and folder into either “part of the site” or “an artifact from the master branch”.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It introduces the need to have lines like this in &lt;code&gt;_config.yml&lt;/code&gt; to prevent unrelated files from being included in the &lt;code&gt;gh-pages&lt;/code&gt; site:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;exclude: ./app, ./lib, ./project.gemspec, ./Gemfile, ./LICENSE, ./Rakefile, ./readme.md, ./features, ./spec&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img src="http://windupmyskirt.files.wordpress.com/2012/03/little-orphan-annie.jpg" alt="Little Orphan Annie"/&gt;&lt;/p&gt;

&lt;h3&gt;&lt;code&gt;git checkout --orphan gh-pages&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;When it comes time to create a GitHub Page for your project, use the above command. This creates a branch that is completely separate from the history of the rest of the repository. You will need to delete the files by running “&lt;code&gt;git rm -rf .&lt;/code&gt;”:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;If you want to start a disconnected history that records a set of paths
that is totally different from the one of &amp;lt;start_point&amp;gt;, then you                                                           
should clear the index and the working tree right after creating the 
orphan branch by running "git rm -rf ." from the top level of the 
working tree. Afterwards you will be ready to prepare your new files,
repopulating the working tree, by copying them from elsewhere,
extracting a tarball, etc.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;— &lt;em&gt;&lt;code&gt;git checkout --help&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After you have an empty branch, you’re ready to get started on your jekyll or HTML site with a clean history and a clear conscience.&lt;/p&gt;

&lt;p&gt;Written by &lt;a rel="author" href="https://plus.google.com/111599109936753790268"&gt;Caleb Thompson&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/9CSF0U34imI/49004256633</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/49004256633</guid><pubDate>Sat, 27 Apr 2013 09:30:00 -0400</pubDate><category>git</category><category>gh-pages</category><category>github</category><category>orphans</category><feedburner:origLink>http://robots.thoughtbot.com/post/49004256633</feedburner:origLink></item><item><title>5 useful tips for a better commit message</title><description>&lt;p&gt;You’re already writing decent commit messages. Let’s see if we can level you up
to awesome. Other developers, especially you-in-two-weeks and
you-from-next-year, will thank you for your forethought and verbosity when they
run &lt;code&gt;git blame&lt;/code&gt; to see why that conditional is there.&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;The first line should always be &lt;a href="http://stopwritingramblingcommitmessages.com/"&gt;50 characters or
less&lt;/a&gt; and that it should be
followed by a blank line. Vim ships with syntax, indent, and filetype plugins
for Git commits which can help here.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add this line to your &lt;code&gt;.vimrc&lt;/code&gt; to add spell checking and automatic wrapping
at the recommended 72 columns to you commit messages.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;autocmd Filetype gitcommit setlocal spell textwidth=72&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Never use the &lt;code&gt;-m &amp;lt;msg&amp;gt;&lt;/code&gt; / &lt;code&gt;--message=&amp;lt;msg&amp;gt;&lt;/code&gt; flag to &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It gives you a poor mindset right off the bat as you will feel that you have
to fit your commit message into the terminal command, and makes the commit
feel more like a one-off argument than a page in history:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git commit -m "Fix login bug"&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A more useful commit message might be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Redirect user to the requested page after login

&lt;a href="https://trello.com/path/to/relevant/card"&gt;https://trello.com/path/to/relevant/card&lt;/a&gt;

Users were being redirected to the home page after login, which is less
useful than redirecting to the page they had originally requested before
being redirected to the login form.

* Store requested path in a session variable
* Redirect to the stored location after successfully logging in the user
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Answer the following questions:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why is this change necessary?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This question tells &lt;a href="https://github.com/thoughtbot/guides/tree/master/code-review"&gt;reviewers of your pull
request&lt;/a&gt;
what to expect in the commit, allowing them to more easily identify and
point out unrelated changes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How does it address the issue?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Describe, at a high level, what was done to affect change.
“&lt;code&gt;Introduce a red/black tree to increase search speed&lt;/code&gt;” or&lt;br/&gt;
“&lt;code&gt;Remove &amp;lt;troublesome gem X&amp;gt;, which was causing &amp;lt;specific description of
issue introduced by gem&amp;gt;&lt;/code&gt;” are good examples.&lt;/p&gt;

&lt;p&gt;If your change is obvious, you may be able to omit addressing this question.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What side effects does this change have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the most important question to answer, as it can point out
problems where you are making too many changes in one commit or branch.
One or two bullet points for related changes may be okay, but five or six
are likely indicators of a commit that is doing too many things.&lt;/p&gt;

&lt;p&gt;Your team should have guidelines and rules-of-thumb for how much can be
done in a single commit/branch.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consider making including a link to the issue/story/card in the commit
message a standard for your project. Full urls are more useful than issue
numbers, as they are more permanent and avoid confusion over which issue
tracker it references.&lt;/p&gt;

&lt;p&gt;This is generally done as the first paragraph after the summary, on line 3.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;img class="illustration" src="http://git-scm.com/images/branching-illustration@2x.png" alt="image"/&gt;&lt;/p&gt;

&lt;p&gt;Having a story in your git log will make a huge difference in how you and others
perceive your project. By taking great care in commit messages, as you do in
your code, you will help to increase overall quality.&lt;/p&gt;

&lt;p&gt;Special thanks to Tim Pope, whose &lt;a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html"&gt;Note About Git Commit
Messages&lt;/a&gt;
literally sets the standard for a good commit message.&lt;/p&gt;

&lt;p&gt;Additional thanks to the creator of Git and a &lt;a href="https://github.com/torvalds/linux/pull/17#issuecomment-5659933"&gt;real stickler for a good commit
message&lt;/a&gt;, Linus
Torvalds.&lt;/p&gt;

&lt;p&gt;Written by &lt;a rel="author" href="https://plus.google.com/111599109936753790268"&gt;Caleb Thompson&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;&lt;h2&gt;Related Articles&lt;/h2&gt;

&lt;p&gt;22 Oct 2008 — &lt;a href="http://robots.thoughtbot.com/post/159806234/simple-test-metrics-in-your-rails-app-and-what-they"&gt;Simple Test Metrics in Your Rails App, and What They Mean&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15 Aug 2009 — &lt;a href="http://robots.thoughtbot.com/post/163627511/a-grand-piano-for-your-violin"&gt;A grand piano for your violin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15 Sep 2012 — &lt;a href="http://robots.thoughtbot.com/post/31584205500/8-new-steps-for-fixing-other-peoples-code"&gt;8 (new) steps for fixing other people&amp;#8217;s code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;17 Apr 2012 — &lt;a href="http://robots.thoughtbot.com/post/21306813001/remote-branch"&gt;Remote Branch&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/5gVDQEWqZXk/48933156625</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48933156625</guid><pubDate>Fri, 26 Apr 2013 11:36:00 -0400</pubDate><category>git</category><category>git commit</category><category>commit message</category><category>guide</category><feedburner:origLink>http://robots.thoughtbot.com/post/48933156625</feedburner:origLink></item><item><title>Redis partial word match -- you (auto)complete me</title><description>&lt;p&gt;&lt;img src="http://img42.imageshack.us/img42/4776/autocompletef.png" alt="Redis autocomplete"/&gt;&lt;/p&gt;

&lt;p&gt;We can use partial word matching to rapidly search strings of text such as Names,
Cities, States, etc.&lt;/p&gt;

&lt;p&gt;We can do this by indexing strings into Redis &lt;a href="http://redis.io/topics/data-types"&gt;sets&lt;/a&gt; based on partial matches of
the string. The indexing process takes a string and breaks it into left-bound
substrings which are placed into the appropriate Redis sets.&lt;/p&gt;

&lt;h2&gt;Partial word matching movie titles&lt;/h2&gt;

&lt;p&gt;In this example we’ll enable partial word matching queries of movie titles.&lt;/p&gt;

&lt;p&gt;The movie titles will be stored in plain text. The keys are simple key-value
pairs that are stored with the key structure &lt;code&gt;movies:id&lt;/code&gt;, where &lt;code&gt;id&lt;/code&gt; is
incremented:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ redis-cli get movies:1
"Bad Santa"
$ redis-cli get movies:2
"Batman"
$ redis-cli get movies:3
"Bad Company"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The movie &lt;code&gt;Batman&lt;/code&gt; would be decomposed into the following sets (assuming that
the indexing started at two characters):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ba
bat
batm
batma
batman
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ll index the movie titles into sets based on partial match of their titles.
To prevent any key collisions in Redis we&amp;#8217;ll create keys with the following
structue &lt;code&gt;index:abc:movies&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;View the indexed ids using Redis &lt;a href="http://redis.io/commands/smembers"&gt;smembers&lt;/a&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ redis-cli smembers index:ba:movies
1) "1"
2) "2"
3) "3"

$ redis-cli smembers index:bat:movies
1) "2"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: The keys for the movie titles have been parameterized (lowercase and spaces
replaced with dashes).&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ll use a Ruby class &lt;code&gt;Autocomplete&lt;/code&gt; to wrap the Redis calls:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# autocomplete.rb
require 'redis'

class Autocomplete
  def initialize(partial_word)
    @partial_word = partial_word
  end

  def movies
    redis.sort "index:#{partial_word}:movies", by: :nosort, get: 'movies:*'
  end

  private

  def redis
    Redis.current
  end

  attr_reader :partial_word
end

movies = Autocomplete.new('bat').movies
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;ll use the &lt;a href="http://redis.io/commands/sort"&gt;sort&lt;/a&gt; command with the &lt;code&gt;by: :nosort&lt;/code&gt; parameter to query the
partial word match index and return the matched movie names.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://plus.google.com/105506419279219045553?rel=author"&gt;Harlow Ward&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Related Reading&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://robots.thoughtbot.com/post/46335890055/redis-set-intersection-using-sets-to-filter-data"&gt;Redis Set Intersection - Using sets to filter data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://robots.thoughtbot.com/post/6325247416/redis-pub-sub-how-does-it-work"&gt;Redis Pub/Sub…how does it work?&lt;/a&gt;&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/KOsuLbvL2ec/48851498400</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48851498400</guid><pubDate>Thu, 25 Apr 2013 09:30:28 -0400</pubDate><category>redis</category><category>autocompletion</category><category>search</category><feedburner:origLink>http://robots.thoughtbot.com/post/48851498400</feedburner:origLink></item><item><title>Episode 45: Tiny Robots Cuddling with other Tiny Robots</title><description>&lt;a href="http://learn.thoughtbot.com/podcast/45"&gt;Episode 45: Tiny Robots Cuddling with other Tiny Robots&lt;/a&gt;: &lt;p&gt;In this week’s podcast we try something a little different. Joe Ferris, Matt Jankowski, Ben Orenstein, and Chad Pytel get together and have a little fun, in what we’re calling “Tiny Robots cuddling with other Tiny Robots”.&lt;/p&gt;

&lt;p&gt;We’d love to get your thoughts on this special format, tweet us &lt;a href="http://twitter.com/thoughtbot"&gt;@thoughtbot&lt;/a&gt; or email &lt;a href="mailto:learn@thoughtbot.com"&gt;learn@thoughtbot.com&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/45"&gt;Episode Notes and Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://itunes.apple.com/us/podcast/giant-robots-smashing-into/id535121941"&gt;Subscribe via iTunes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast.xml"&gt;Subscribe via RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/45.mp3"&gt;Direct Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/jIPk72gqxtk/48684492350</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48684492350</guid><pubDate>Tue, 23 Apr 2013 06:00:30 -0400</pubDate><category>fun</category><feedburner:origLink>http://robots.thoughtbot.com/post/48684492350</feedburner:origLink></item><item><title>Vim Splits - Move Faster and More Naturally</title><description>&lt;p&gt;Most of us are Vim users and have tweaked our favorite editor for speed and convenience. See &lt;a href="https://github.com/thoughtbot/dotfiles/blob/master/vimrc"&gt;thoughtbot&amp;#8217;s dotfiles&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of my favorite tools is the window split. Here is a quick splits overview and configurations to use them more effectively.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm4.staticflickr.com/3593/3298193261_a9d67baf95_b.jpg" alt="7_10_split"/&gt;&lt;/p&gt;

&lt;h2&gt;The basics&lt;/h2&gt;

&lt;p&gt;Create a vertical split using &lt;code&gt;:vsp&lt;/code&gt; and horizontal with &lt;code&gt;:sp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By default, they duplicate the current buffer. This command also takes a filename:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:vsp ~/.vimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can specify the new split height by prefixing with a number:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:10sp ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Close the split like you would close vim:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:q
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Easier split navigations&lt;/h2&gt;

&lt;p&gt;We can use different key mappings for easy navigation between splits to save a
keystroke. So instead of &lt;code&gt;ctrl-w&lt;/code&gt; then &lt;code&gt;j&lt;/code&gt;, it&amp;#8217;s just &lt;code&gt;ctrl-j&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nnoremap &amp;lt;C-J&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-J&amp;gt;
nnoremap &amp;lt;C-K&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-K&amp;gt;
nnoremap &amp;lt;C-L&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-L&amp;gt;
nnoremap &amp;lt;C-H&amp;gt; &amp;lt;C-W&amp;gt;&amp;lt;C-H&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;More natural split opening&lt;/h2&gt;

&lt;p&gt;Open new split panes to right and bottom, which feels more natural than Vim&amp;#8217;s
default:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set splitbelow
set splitright
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Resizing splits&lt;/h2&gt;

&lt;p&gt;Vim&amp;#8217;s defaults are useful for changing split shapes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"Max out the height of the current split
ctrl + w _

"Max out the width of the current split
ctrl + w |

"Normalize all split sizes, which is very handy when resizing terminal
ctrl + w =
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;More split manipulation&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;"Swap top/bottom or left/right split
Ctrl+W R

"Break out current window into a new tabview
Ctrl+W T

"Close every window in the current tabview but the current one
Ctrl+W o
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;:help!&lt;/h2&gt;

&lt;p&gt;As with everything in Vim, for more information, check the well-written
helpfiles. In Vim, &lt;code&gt;:help splits&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Vim Meetups&lt;/h2&gt;

&lt;p&gt;Come talk splits at a Vim Enthusiast Meetup near you:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.meetup.com/Stockholm-Vim/"&gt;Stockholm Vim Meetup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.meetup.com/The-Boston-Vim-Meetup/"&gt;Boston Vim Meetup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://groups.google.com/forum/?hl=en&amp;amp;fromgroups#!forum/vimsf"&gt;San Francisco&amp;#8217;s VimSF Google Group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Photo credit: &lt;a href="http://www.flickr.com/photos/aressa/3298193261"&gt;Andrew Ressa on
Flickr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://plus.google.com/116006351214905134217/"&gt;Adarsh Pandit&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/NF6DJ47PngE/48275867281</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48275867281</guid><pubDate>Thu, 18 Apr 2013 09:30:09 -0400</pubDate><category>vim</category><category>self-vimprovement</category><category>splits</category><category>vimrc</category><feedburner:origLink>http://robots.thoughtbot.com/post/48275867281</feedburner:origLink></item><item><title>Online presentation with thoughtbot and Heroku</title><description>&lt;p&gt;&lt;a href="https://twitter.com/adarshp"&gt;Adarsh&lt;/a&gt;, &lt;a href="https://twitter.com/alexbaldwin"&gt;Alex&lt;/a&gt;, and &lt;a href="https://twitter.com/croaky"&gt;I&lt;/a&gt; are giving a free online presentation with &lt;a href="https://twitter.com/AbePursell"&gt;Abe&lt;/a&gt; from Heroku about how their platform fits into our process. Over 1,400 people have registered so far! The details:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Tomorrow, April 17&lt;/li&gt;
&lt;li&gt;Once at 7:00am PST (2:00pm GMT / 7:30pm IST)&lt;/li&gt;
&lt;li&gt;A second time at 10:00am PST (5:00pm GMT / 10:30pm IST)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://buff.ly/16EVPfn"&gt;&lt;img src="http://media.tumblr.com/61d93c192999d9a113f6e219ff4240b9/tumblr_inline_mkv167JX0x1qz4rgp.png" alt="Heroku event"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://buff.ly/16EVPfn"&gt;RSVP here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will be live coding(!), making a single change to a live web application hosted on Heroku within the context of a common process for us:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Campfire for real-time communication and alerts.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thoughtbot/guides/tree/master/product-management/trello"&gt;Trello for managing the task&lt;/a&gt; and tracking discussion.&lt;/li&gt;
&lt;li&gt;Our &lt;a href="https://github.com/thoughtbot/guides/tree/master/protocol"&gt;git protocol&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;GitHub pull request-based &lt;a href="https://github.com/thoughtbot/guides/tree/master/code-review"&gt;code review&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Shortcuts from &lt;a href="https://github.com/thoughtbot/dotfiles"&gt;thoughtbot/dotfiles&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Staging and production environments on Heroku.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We will also show a few other goodies:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Heroku config variables.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://addons.heroku.com"&gt;Heroku addons&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.heroku.com/articles/dyno-size"&gt;Heroku 2x dynos&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Using &lt;a href="http://robots.thoughtbot.com/post/8392002973/7-minute-ab-impatient-mans-load-tests-for-a-heroku"&gt;Apache Bench&lt;/a&gt; for simple load and memory tests.&lt;/li&gt;
&lt;li&gt;Each dyno handling about ~1,000 requests per minute for a static site.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/defunkt/unicorn"&gt;Unicorn&lt;/a&gt;, &lt;a href="http://www.sinatrarb.com"&gt;Sinatra&lt;/a&gt;, and &lt;a href="http://patshaughnessy.net/2012/3/23/why-you-should-be-excited-about-garbage-collection-in-ruby-2-0"&gt;Ruby 2.0&amp;#8217;s Copy-On-Write&lt;/a&gt; garbage collection.&lt;/li&gt;
&lt;li&gt;Using &lt;a href="https://blog.heroku.com/archives/2013/3/19/log2viz"&gt;log2viz&lt;/a&gt; for performance and memory visibility.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We will share an open source web application and a read-only Trello board during the presentation. There will be a question-and-answer session at the end.&lt;/p&gt;

&lt;p&gt;Hope to see you online! &lt;a href="http://buff.ly/16EVPfn"&gt;RSVP here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;UPDATE: Heroku has posted &lt;a href="http://www.youtube.com/watch?v=Y1oNCb-S_aM"&gt;a recording to YouTube&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/GLaffxBAXh8/48163621187</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48163621187</guid><pubDate>Tue, 16 Apr 2013 21:11:00 -0400</pubDate><category>heroku</category><category>playbook</category><feedburner:origLink>http://robots.thoughtbot.com/post/48163621187</feedburner:origLink></item><item><title>Episode 44: I feel the opposite of burnt out</title><description>&lt;a href="http://learn.thoughtbot.com/podcast/44"&gt;Episode 44: I feel the opposite of burnt out&lt;/a&gt;: &lt;p&gt;In this week’s podcast, Ben Orenstein is joined by Chad Fowler, author, speaker, and CTO of 6wunderkinder. Ben and Chad discuss Chad’s recent move to Berlin and 6wunderkinder, what a CTO does, getting back to coding, the early Ruby community, who Chad wants to hire, predicting success of new hires, and what makes a truly good developer, favorite interview questions, how Chad’s interviewing process has changed over time, how age and experience can change your perspective, how Chad built a great team, and what he might write about in the future. They also discuss Chad’s new tattoo, his regrets, meditation, therapy, gaining control over your mind, and much, much more.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/44"&gt;Episode Notes and Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://itunes.apple.com/us/podcast/giant-robots-smashing-into/id535121941"&gt;Subscribe via iTunes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast.xml"&gt;Subscribe via RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learn.thoughtbot.com/podcast/44.mp3"&gt;Direct Download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/RvT01SfiWJw/48040191074</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/48040191074</guid><pubDate>Mon, 15 Apr 2013 10:00:27 -0400</pubDate><category>ruby on rails</category><category>ruby</category><category>software development</category><feedburner:origLink>http://robots.thoughtbot.com/post/48040191074</feedburner:origLink></item><item><title>Ruby Science Redesigned</title><description>&lt;p&gt;We just pushed a new design for &lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newdesign"&gt;Ruby Science&lt;/a&gt;. Previous purchasers and &lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=prime"&gt;Prime&lt;/a&gt; subscribers can grab the update &lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newdesign"&gt;on Learn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The new design includes a new layout, which is much more appropriate for a book. We updated the typeface and font size to improve the experience when reading the book on a screen as opposed to a printed page. The margin size is also greatly reduced, making it easier to zoom in on a laptop screen and bring the text right to the edges.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ui.thoughtbot.com/assets/ruby-science-before-and-after.png" alt="Before and After"/&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.thoughtbot.com/products/13-ruby-science?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=newdesign"&gt;Get your copy of Ruby Science today&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Now Available For Free With Learn Prime&lt;/h2&gt;

&lt;p&gt;We recently &lt;a href="http://robots.thoughtbot.com/post/46249965247/introducing-learn-prime-subscription-access-to"&gt;announced the launch&lt;/a&gt; of our subscription service: &lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=prime"&gt;Learn Prime&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For just $99/month, you get ongoing access to everything we teach, including books like Ruby Science. You&amp;#8217;ll even get access to all our in-person and online workshops. Get access to exclusive subscriber content, as well as access to our private Campfire room, where you can get live help from thoughtbot designers and developers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.thoughtbot.com/products/14-prime?utm_source=giantrobots&amp;amp;utm_medium=blog&amp;amp;utm_campaign=prime"&gt;Subscribe now&lt;/a&gt;.&lt;/p&gt;</description><link>http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/K6xJLLYhUws/47629504269</link><guid isPermaLink="false">http://robots.thoughtbot.com/post/47629504269</guid><pubDate>Wed, 10 Apr 2013 13:16:43 -0400</pubDate><category>ruby</category><category>ruby science</category><category>design</category><category>font</category><category>typography</category><feedburner:origLink>http://robots.thoughtbot.com/post/47629504269</feedburner:origLink></item></channel></rss>
