<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Highgroove Studios - Blog - Pit-side with Highgroove</title>
 
 <link href="http://highgroove.com/" />
 <updated>2012-02-22T01:04:52-05:00</updated>
 <id>http://highgroove.com/</id>
 <author>
   <name>Highgroove Studios</name>
   <email>hello@highgroove.com</email>
 </author>

 
   <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/highgroove" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="highgroove" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
     <title>Why Highgroove has a Personal Trainer</title>
     <link href="http://highgroove.com/articles/2012/02/21/why-highgroove-has-a-personal-trainer.html" />
     <updated>2012-02-21T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/21/why-highgroove-has-a-personal-trainer.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://i.imgur.com/fxgnx.png" alt="Brule" style="float: right;" width="200" height="200" /&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove, we have a personal trainer, &lt;a href="http://highgroove.com/about/cherri.html"&gt;Cherri&lt;/a&gt;, on-staff and on-site, available twice a week to us, scheduled via Appointment Slots using Google Calendar.  Our personal trainer has been with us since December of last year, and we just added more sessions.  We have been delighted at the opportunity to get in shape (although, perhaps, temporarily less thrilled when "core day" came around). Personally, having someone motivate us to exercise -- someone who thoroughly knows what they are doing was exactly the motivation I needed to start working out again. But we've also realized getting a gym session in during the afternoon has benefits for developing software (along with developing sweet abs).&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;The sessions are personally catered to each of us, last just thirty intense minutes, and with the gym just downstairs, it's a quick walk over to start working out. It's an even quicker walk when Cherri sends you an email, reminding you that your session starts in 1 minute.  With such a short work out session, and scheduled in the middle of the work day (almost all sessions are after lunch), you would think it would cause a break in productivity, but the opposite actually happens.&lt;/p&gt;

&lt;p&gt;In fact, Lifehacker has posted about the &lt;a href="http://lifehacker.com/5885948/try-exercising-during-the-middle-of-the-day-for-an-energy-and-productivity-boost"&gt;benefits of a workday workout&lt;/a&gt;, explaining that it improves energy and alertness as well as productivity. The article fits my and other Highgroover's experiences perfectly: working out gives an energy boost that used to be gained by an extra double-shot of espresso, and also gives us time to mentally work out the programming problems wracking our brains. We can return to work refreshed (if a little sweatier) and ready to tackle things from a new perspective. It almost seems counter-intuitive, but after a work out, we have all remarked on the productivity increase.  It's real!&lt;/p&gt;

&lt;p&gt;What healthy habits give you a productivity boost?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Working Hard or Working Efficiently?</title>
     <link href="http://highgroove.com/articles/2012/02/21/efficiency-over-effort.html" />
     <updated>2012-02-21T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/21/efficiency-over-effort.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://mimg.ugo.com/201006/48328/cuts/a-pharaoh-to-remember_288x288.jpg" alt="Bender" style="float: right;" width="200" height="200" /&gt;&lt;/p&gt;

&lt;p&gt;Companies often feel that they are getting the most out of their employees if everyone is working as hard as possible for as long as possible.  However, this can be exhausting on the employees and can lead to diminishing returns.  We feel that the better approach is to emphasize efficiency over effort, and our level of productivity speaks for itself.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Working in a ROWE gives us an advantage in working efficiently because we can better handle common productivity pitfalls.  Stress rears its ugly head in many projects.  In a typical 9-to-5 (or even later) the employee is chained to their chair and must work until the end of the day, or until a moment of escape presents itself.  How much work is actually done in those last few hours as stress goes up and morale goes down?  Because we have the freedom to work when we want we are able to step away from our projects for a few hours, do something that relaxes us, and try to tackle the problem in a better mindset.  Given the break time we may work fewer hours in the day overall, but those fewer hours produced more than the stressed employee.  The resulting code is also likely of a higher quality due to the more focused employee making fewer careless mistakes.&lt;/p&gt;

&lt;p&gt;We are also able to avoid burnout by taking advantage of productivity bursts.  Every developer has been on a programming tear, where they are able to crank out code at a blistering pace and don't want to stop for fear of losing momentum.  When they are done they may have completed a day's work in a few hours.  What to do next?  Whatever you want, as long as you're meeting your client's needs.&lt;/p&gt;

&lt;p&gt;Emphasizing efficiency over effort leads to happier employees, fewer errors, a higher quality product, and happy clients.  Everyone wins.  What other strategies can you use to maximize efficiency?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Another Reason To Use Github</title>
     <link href="http://highgroove.com/articles/2012/02/20/github-support.html" />
     <updated>2012-02-20T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/20/github-support.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://octodex.github.com/images/okal-eltocat.jpg" alt="Super Octocat" style="float: right;" width="200" height="200" /&gt;&lt;/p&gt;

&lt;p&gt;While getting to know the very sweet &lt;a href="http://developer.github.com/"&gt;Github Api v3&lt;/a&gt;, I ran into a little bug when trying to page though results coming back from the service. While it was frustrating at the time, Github's support and resolution blew me out of the water.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;For a new in-house project, we would like to be able to grab the commit messages for a number of our repositories that live in Github. Using the &lt;a href="https://github.com/pengwynn/octokit"&gt;octokit gem&lt;/a&gt; with the &lt;code&gt;auto_traversal&lt;/code&gt; option turned on, this is trivially easy. Because of a bug in the Github api, when the gem tried to page though the results, the link it got for the next page was always the same. This caused an infinite loops of http requests, and me to try to pull all of my hair out.&lt;/p&gt;

&lt;p&gt;Once I threw a few &lt;a href="https://github.com/pry/pry"&gt;pry&lt;/a&gt; bindings into the project and was able to track the issue, I was able to easily hunt down Github's support for issues with the API (it was right on the docs page for the API). All that was required to get a fix deployed for the issue was a quick email with steps to reproduce the bugs and less than 24 hours of patience!&lt;/p&gt;

&lt;p&gt;The fact that the Github crew was able to submit a fix to their live service before I could submit a pull request to octokit with a workaround reminds me why they stand out in my mind as a great web app. Not only is their site feature rich and easy to use, but they've got a great team backing the technology up. That's why we at Highgroove trust them with our code and why we recommend them to clients.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Live from StartupRiot MAKE</title>
     <link href="http://highgroove.com/articles/2012/02/18/live-from-startupriot-make.html" />
     <updated>2012-02-18T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/18/live-from-startupriot-make.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6897427255/" title="Lots of MAKEing going on. Building companies, products, games at @startupriot MAKE by highgroove, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7039/6897427255_eb657a522c_m.jpg" width="240" height="180" alt="Lots of MAKEing going on. Building companies, products, games at @startupriot MAKE" align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://startupriot.com/"&gt;StartupRiot MAKE&lt;/a&gt; event kicked off last night at ATDC with the help of &lt;a href="http://sanjayparekh.com/"&gt;Sanjay Parekh&lt;/a&gt; and some very awesome sponsors and teams.&lt;/p&gt;

&lt;p&gt;We're happy to be a part of this awesome event.  At 5 pm on Friday, teams started trickling in and sponsors started setting up displays.  The food arrived and many people began networking and planning already.&lt;/p&gt;

&lt;p&gt;At 6 pm, Sanjay announced the teams, and each team got up and spoke about what they were building, and what they needed -- be it a designer, some mobile development help, or back-end development.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;There are some awesome prizes, but I am pretty sure the teams that are here, while they are happy to win, are actually here because they enjoy making and building things using technology.  You can actually tell, because in addition to building products (we've already seen a few working demos), they're helping each other, offering encouragement, and feedback.&lt;/p&gt;

&lt;p&gt;A few of us from Highgroove are here this weekend offering help in the form of knowledge and programming chops.  Since we've built products and services for companies both big and soon-to-be-big, we're pretty opinionated about what we've seen that works and doesn't work in a modern web application.  Our actual real service, though, that we're offering is something that comes natural to us:  "Just Keeping it Simple" and saying "No" to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complicated features (keep it simple!)&lt;/li&gt;
&lt;li&gt;overly generic solutions (hyper-specialize instead)&lt;/li&gt;
&lt;li&gt;building it yourself (instead of leveraging open source)&lt;/li&gt;
&lt;li&gt;scaling too soon (start small, scale later)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Good luck teams!&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Talk on Visualizing Scaling</title>
     <link href="http://highgroove.com/articles/2012/02/17/tech-talk-on-visualizing-scaling.html" />
     <updated>2012-02-17T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/17/tech-talk-on-visualizing-scaling.html</id>
     <content type="html">&lt;p&gt;&lt;img src="/images/blog/distributed-data-animations.png" align="right"&gt;&lt;/p&gt;

&lt;p&gt;This week's Tech Talk was on Visualizing Scaling, and Consistent Hashing techniques for scaling data.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://highgroove.com/about/patrick.html"&gt;Patrick&lt;/a&gt; talked through several visualizations he created in HTML5 to visually explain many common scaling techniques.&lt;/p&gt;

&lt;p&gt;If you've heard of the techniques and algorithms: "sharding" or "master-slave", or even "consistent hashing" for distributing data across servers, but never really known how they work, this talk goes through the basics and shows visually how data can be scaled out across multiple servers.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;"I never really understood some of these techniques until I saw them visually", says Patrick, who has implemented many of these techniques for Highgroove's many clients.  He details the pros and cons and even how and when to start considering these techniques for scaling.&lt;/p&gt;

&lt;p&gt;Check out the animations here on Github:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vanstee/distributed-data"&gt;https://github.com/vanstee/distributed-data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, be sure to check out the video on Vimeo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vimeo.com/36985167"&gt;Consistent Hashing Tech Talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interested in attending (or even presenting) at our weekly Tech Talks?  Check out our upcoming &lt;a href="https://www.facebook.com/highgroove/events"&gt;Highgroove Events on Facebook&lt;/a&gt;.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>If the Shoe Fits, Ship it!</title>
     <link href="http://highgroove.com/articles/2012/02/17/if-the-shoe-fits-ship-it.html" />
     <updated>2012-02-17T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/17/if-the-shoe-fits-ship-it.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://r.ebay.com/t38iSW"&gt;&lt;img src="http://twotoneatl.com/wp-content/uploads/2012/02/Screen-Shot-2012-02-17-at-1.17.51-AM.jpg" width="240", height="207" alt="Squirrel Shipping Sweet Cycling Shoes" align="right"/&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In January of 2012, after spending the holidays 'funemployed' (OK, just on vacation) down in sunny Florida logging some &lt;a href="http://twotoneatl.com/tag/rapha500/"&gt;EPIC miles&lt;/a&gt;, I very excitedly boarded the Highgroove &lt;a href="http://highgroove.com/articles/2011/12/15/tracking-time-the-rowe-way.html"&gt;ROWE&lt;/a&gt;-boat as our first Account Director.&lt;/p&gt;

&lt;p&gt;The month of January left me dazed but not confused. Working in a ROWE environment means results are expected immediately (and that results are all that matter). I hit the ground running and quickly found that everyone here is equally vested each project's success. That is to say, pardon the pun: "the rising tide lifts all boats" here at Highgroove.  By leveraging constant communication, the best tools, pair programming, code audits, and project retrospectives -- we truly are an &lt;a href="http://highgroove.com/articles/2010/10/29/agile-development-agile-product.html"&gt;agile&lt;/a&gt; shop.&lt;/p&gt;

&lt;p&gt;Read on to find out how I learned about what we do best, what makes us different, and what that means to me as our Account Director.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;After only having been on the job not even two months, I am still new but no longer the new guy.  Reading &lt;a href="http://highgroove.com/articles/2011/04/05/month-two-at-highgroove.html"&gt;Andy's Post 2 Months in at Highgroove&lt;/a&gt;, I feel humbled to be &lt;a href="http://highgroove.com/about.html"&gt;listed alongside&lt;/a&gt; some pretty amazing colleagues here. Similar to &lt;a href="http://highgroove.com/articles/2012/01/16/getting-in-the-groove.html"&gt;Will's First Reactions at Highgroove&lt;/a&gt;, I've been good friends with several Highgroovers for years. Plus, I knew Highgroove worked on amazing projects with even more amazing clients.&lt;/p&gt;

&lt;h2&gt;What we do Best&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;We know that our clients benefit from constant communication with developers.&lt;/em&gt; Small issues are consistently caught before they become large problems. Our collaborative environment is filled with brilliant people producing refined, simple solutions in Ruby and Ruby on Rails to complicated and challenging backend software application projects. Not to mention, those brilliant people don’t have to freak out if they're running "late" into the office because of the &lt;a href="http://www.nytimes.com/2011/01/21/us/21atlanta.html?_r=1_"&gt;worst traffic in the country&lt;/a&gt;. As Daniel points out: &lt;a href="http://highgroove.com/articles/2011/06/08/first-month-down.html"&gt;There is no late to the office&lt;/a&gt;, since work can be done (and is done) when and where it makes sense. Highgroove uses collaborative, agile tools because they lead to extremely high quality code at every stage of a project. My long time friend and resident Methodologist, Chris Kelly, emphasized this in a &lt;a href="http://highgroove.com/articles/2011/03/21/iterations-are-dead-long-live-iterations.html"&gt;great post on iterations&lt;/a&gt; last year. Let's review:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We're Project-Manager-less. We offer clients direct Contact with developers who actually do the work. No watered down communication or confusion.&lt;/li&gt;
&lt;li&gt;We're hyper-specialists. We're experts in backend web development in Ruby and Ruby on Rails. We know what we're good at, and stick to it.&lt;/li&gt;
&lt;li&gt;We're ROWE. We don't care when or where work happens, all that matters is that the work gets done.&lt;/li&gt;
&lt;li&gt;We're Agile. Highgroove walks the walk and follows all &lt;a href="http://agilemanifesto.org/principles.html"&gt;12 Principles&lt;/a&gt; on ALL projects.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;What makes us Different&lt;/h2&gt;

&lt;p&gt;Ok, those are neat characteristics but what REALLY makes us different? Our friends at &lt;a href="http://matchstic.com"&gt;Matchstic&lt;/a&gt; helped us uncover our Core Values (Attributes) at their &lt;a href="http://matchstic.com/blog/2011/03/brand-camp-may/"&gt;Brand Camp&lt;/a&gt;. Hear it straight from the horse's mouth, as &lt;a href="http://highgroove.com/about/charles.html"&gt;CBQ&lt;/a&gt; &lt;a href="http://vimeo.com/27440068"&gt;shares the camp's impact on our business.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Core Values are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Personable&lt;/li&gt;
&lt;li&gt;Optimistic&lt;/li&gt;
&lt;li&gt;Trusting&lt;/li&gt;
&lt;li&gt;Craftsmanship&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Knowing our core values helps us not only know what shoes fit in the client department, but also how to hire, how to communicate and what firms we should partner with. I have found (like all Highgroovers) that I identified with each attribute, which is how I knew I was at the right place.&lt;/p&gt;

&lt;h2&gt;What that Means to me as our Account Director&lt;/h2&gt;

&lt;p&gt;Now back to the 'shipping'. Since we're an agile shop, one of my favorite parts about working at Highgroove is our 'Bias Towards Action'. We just &lt;em&gt;Ship it!&lt;/em&gt; and then we iterate and ship it again until it's the best it can be. As Account Director this all means one thing:  The value we offer resides in our proven process and unique brand. Our office manager &lt;a href="http://highgroove.com/about/megan.html"&gt;Megan&lt;/a&gt; underscored the importance of this this process &lt;a href="http://highgroove.com/articles/2011/01/20/a-day-in-the-life-of-agile-hands-on-workshop.html"&gt;at an Agile Workshop she attended&lt;/a&gt;, because it supports client needs at the highest level, encourages focused development, and fundamentally promotes efficiency. And there's where the rubber meets the road and why &lt;a href="http://highgroove.com/faq.html"&gt;being in the 'Highgroove'&lt;/a&gt; truly sets us apart. We know what shoe fits whether it means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the right client fit for a project,&lt;/li&gt;
&lt;li&gt;the right tools and&lt;/li&gt;
&lt;li&gt;the right team&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I am now a bona-fide member of the just 'Ship It' club, in my both my personal and work life. At Highgroove we know what fits best, we know what sets us apart, and we just 'ship it!'&lt;/p&gt;

&lt;p&gt;Have you ever thought about what makes your company really unique?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>You Must Teach To Be Taught</title>
     <link href="http://highgroove.com/articles/2012/02/14/you-must-teach-to-be-taught.html" />
     <updated>2012-02-14T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/14/you-must-teach-to-be-taught.html</id>
     <content type="html">&lt;div style="width:260px;float:right;"&gt;
  &lt;a title="Athens Code Retreat" href="https://img.skitch.com/20120215-bs3cr5ewana1mbgqxrfbkbxn7p.png"&gt;
    &lt;img src="https://img.skitch.com/20120215-bs3cr5ewana1mbgqxrfbkbxn7p.png" width="240", height="207" alt="Athens Code Retreat"/&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Waaaayyy back in December, I had the pleasure of &lt;a href="http://highgroove.com/articles/2011/12/13/lessons-learned-at-global-day-of-coderetreat.html"&gt;attending a code
retreat&lt;/a&gt;.
In that post, I discussed what I learned.&lt;/p&gt;

&lt;p&gt;This month, I had the pleasure of facilitating a &lt;a href="http://coderetreat.org"&gt;code
retreat&lt;/a&gt; &lt;a href="http://www.eventbrite.com/event/2604969534"&gt;a few weeks
ago&lt;/a&gt;.  Thanks to
&lt;a href="http://highgroove.com"&gt;Highgroove&lt;/a&gt;, &lt;a href="https://www.tapjoy.com/"&gt;TapJoy&lt;/a&gt;,
&lt;a href="http://www.fourathens.com/"&gt;FourAthens&lt;/a&gt;, and my co-coordinator &lt;a href="https://twitter.com/#!/travisdouce"&gt;Travis
Douce&lt;/a&gt;, the Athens Code Retreat was a resounding
success.&lt;/p&gt;

&lt;p&gt;Also, a special shout out to our &lt;a href="http://coderetreat.org/events/coderetreat-rubyfuza-cape-town"&gt;Code Retreat homies in South
Africa&lt;/a&gt; led by
&lt;a href="http://coreyhaines.com/"&gt;Corey Haines&lt;/a&gt;, who handed off the baton to us late in
their day but early in ours.&lt;/p&gt;

&lt;p&gt;Read on to find out how lessons learned from facilitating compares to attending,
how the general "You" actually means "I" in the blog title, and how many times
it takes (me) to learn the four rules of simple design.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;The purpose of a Code Retreat is to get better, to practice one's craft in
a setting without the pressure of "getting it done, yesterday(tm)."  Throughout
the Code Retreat, we emphasize the &lt;a href="http://c2.com/cgi/wiki?XpSimplicityRules"&gt;4 rules of simple
design&lt;/a&gt;.  Another way to paraphrase
them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tests pass.&lt;/li&gt;
&lt;li&gt;Good naming.&lt;/li&gt;
&lt;li&gt;No duplication / Don't repeat yourself (DRY).&lt;/li&gt;
&lt;li&gt;Small.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;To facilitate self-improvement, we dedicate the last session of the day to the
closing circle.  In the closing circle, three questions are asked of every
participant.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What did you learn?&lt;/li&gt;
&lt;li&gt;What most surprised you?&lt;/li&gt;
&lt;li&gt;What are you going to do differently going forward?&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In my original &lt;a href="(http://highgroove.com/articles/2011/12/13/lessons-learned-at-global-day-of-coderetreat.html"&gt;blog
post&lt;/a&gt;),
I boldly claimed that one could code the Game of Life in 45 minutes if and only
if they practice four or five times and skimp on tests.  Oh, how wrong I was!&lt;/p&gt;

&lt;p&gt;One pair, which included &lt;a href="http://highgroove.com/about/andy.html"&gt;Andy&lt;/a&gt;, managed
to write a completely functional version in 30 minutes.  They even had time to
invent their own spaceship.  How is this even possible?  Other groups took the
fast and loose approach.  "We know the problem domain.  We have the technology.
Tests?  Where we're going, we don't need no stinkin' tests!"&lt;/p&gt;

&lt;p&gt;What was the first pair's secret sauce?  TESTS! GOOD NAMES! DRY! SMALL METHODS!
SMALL CODE BASE!  Amazing!&lt;/p&gt;

&lt;p&gt;I learned magnitudes more facilitating than I did attending. I saw novel
approaches that impressed and stretched my understanding of the problem domain.
I saw good coding practices win out over the quick and dirty style again and
again.&lt;/p&gt;

&lt;p&gt;What have you learned when teaching that you didn't learn as the student?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Mailcatcher: Making email testing a breeze</title>
     <link href="http://highgroove.com/articles/2012/02/09/mailcatcher%3A-making-email-testing-a-breeze.html" />
     <updated>2012-02-09T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/09/mailcatcher%3A-making-email-testing-a-breeze.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://mailcatcher.me" title="Mailcatcher is really awesome!!!"&gt;&lt;img src="http://mailcatcher.me/logo.png" alt="Mailcatcher Logo" style="float:right;"&gt;&lt;/a&gt;
One of my least favorite chores as a developer is dealing with email. I’m not talking about my inbox. That is a post for another day ;). I’m talking about emails sent by web applications. Whether it is a sign up confirmation email, a receipt from a purchase, or reminder for your dog’s birthday. Chances are, if you have a web application, it sends email.&lt;/p&gt;

&lt;p&gt;Traditionally, my workflow for testing these emails has not been very elegant or even efficient. It would either involve creating a bunch of users with different emails accounts I own, or telling the back-end to send all emails to my email address. While both of these work to some extent, the former is very time consuming and the later isn’t really testing the system the way it is meant to be used.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mailcatcher.me/"&gt;Mailcatcher&lt;/a&gt; one-ups both of these methods big time. Mailcatcher provides you with a local SMTP server for you to send your emails to in your development environment. Mailcatcher also provides you with a webmail interface to view all the emails your system has sent.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Mailcatcher is written in ruby and is available as a &lt;a href="https://rubygems.org/gems/mailcatcher/"&gt;gem&lt;/a&gt;. The gem's site offers detailed instructions on how to use Mailcatcher with a Rails app or even a PHP app. Without going into the details here, after you have installed Mailcatcher, you basically just set whatever is sending mail to use Mailcatcher's SMTP server. Then any emails sent by your site will be collected in Mailcatcher's webmail interface. Check it out:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20120209-fxny14wci2nf1y8gqa2i6635sx.jpg" width="520" style="float:none" alt="Mailcatcher UI"&gt;&lt;/p&gt;

&lt;p&gt;Mailcatcher has really eased the pain of dealing with emails in web application development. What are some tools you have found or made that have made development more fun for you?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Red, Green, Refactor - The Tools For Success</title>
     <link href="http://highgroove.com/articles/2012/02/07/red%2C-green%2C-refactor---the-tools-for-success.html" />
     <updated>2012-02-07T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/02/07/red%2C-green%2C-refactor---the-tools-for-success.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/andyarmstrong/89444201/" title="Tools by AndyArmstrong, on Flickr"&gt;&lt;img src="http://farm1.staticflickr.com/16/89444201_874ccb4d88.jpg" width="375" height="500" alt="Tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's easy to say "We're agile" and "We use Behavior/Test Driven Development" and
thus "we use the right tools to empower our developers!" but what are those
tools?  For me that discussion is entirely about the tool stack you choose, how
that stack empowers you as a developer to do things right the first time.
Luckily thanks to the ruby community as a whole we have a large number of
high-quality choice to choose between.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Generally when we talk about TDD and being agile, beyond the process of choosing
features to deliver the maximum customer facing value, we refer back to the simplest
possible workflow of "Red/Green/Refactor." Within that workflow you write tests
that fail, make them pass (with the focus on getting that done without
polishing), then refactoring, to polish where necessary.  The subject of testing
is a huge one with a large body of prose already written on the subject.
&lt;a href="http://railsrx.com/"&gt;Rails Test Prescriptions&lt;/a&gt; and
&lt;a href="http://pragprog.com/book/achbd/the-rspec-book"&gt;The RSpec Book&lt;/a&gt;
are fine examples of such, along with a huge menagerie of
&lt;a href="http://avdi.org/devblog/2011/09/06/making-a-mockery-of-tdd/"&gt;blog posts&lt;/a&gt;,
&lt;a href="http://rubyrogues.com/what-not-to-test/"&gt;podcasts&lt;/a&gt;, and
&lt;a href="http://railscasts.com/episodes/275-how-i-test"&gt;screencasts&lt;/a&gt; to choose from.&lt;/p&gt;

&lt;p&gt;I propose a slightly different day-to-day workflow that I see used to great success.&lt;/p&gt;

&lt;ol start="0"&gt;
&lt;li&gt; Hack around and choose your course &lt;/li&gt;
&lt;li&gt; Red - write some tests that fail but will pass when your code meets your needs&lt;/li&gt;
&lt;li&gt; Green - the code is written, the tests pass, life is good. &lt;/li&gt;
&lt;li&gt; Refactor - Don't Repeat Yourself (DRY your code out).  Or don't, if Ya Ain't Gonna Need It (YAGNI). &lt;/li&gt;
&lt;li&gt; Continuous Integration &lt;/li&gt;
&lt;li&gt; PANIC OVER SECURITY &lt;/li&gt;
&lt;li&gt; Ride Bikes &lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;This isn't the "pure" TDD process, but one that just adds a couple of unspoken
facets of the process that are already used widely, just don't fall into the
pithy "Red/Green/Refactor" process.&lt;/p&gt;

&lt;p&gt;Ruby has a functional programming feeling with its composition of methods,
distinction of methods with side-effects from those that do not (via the !
suffix), and it comes with some variety of REPL via IRB (or the new awesomeness
in Pry).  This allows us as developers to spend some time touching code and
experimenting before we decide exactly how we might like a function to operate,
and thus before getting into the main development workflow for a given feature.&lt;/p&gt;

&lt;p&gt;Tools to support step 0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.ruby-lang.org/en/documentation/quickstart/"&gt;Irb&lt;/a&gt; - you already
know about this but it's easy to overlook.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pry.github.com/"&gt;Pry&lt;/a&gt; - the new slickness that is 1-part Irb
replacement, 1-part debugger, and a pinch (or three) of awesome.  Watch the
screencast to get a feel for it!&lt;/li&gt;
&lt;li&gt;good-ole-pencil-and-paper, a whiteboard, some origami paper&lt;/li&gt;
&lt;li&gt;whatever tool gives you a feeling for the right way to proceed without being
trapped in analysis-paralysis.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Once you're ready to write some tests that will fail, you likely already have a
test framework of choice, and even a workflow for running those tests.  You may
run them from within your editor, have a terminal window ready, willing, and able
to run them with a single command (and a shortcut into your history like
ctrl-R), or you may let something else automagically run them for you and report
back.&lt;/p&gt;

&lt;p&gt;At Highgroove many of us find a combination of running tests manually and
automatic test running and reporting to be most useful.  To accomplish this I
use the testing framework selected for the project along with Spork and Guard.
Spork is a test server that constantly keeps your rails code loaded and ready to
be tested rather than loading each time in a rake task.  Spork should be your
first step to speeding up slow-running test-suites.  Guard is Spork's right hand
man.  It watches code for changes on disk and automagically runs the correct
associated tests.  Guard will even notify you via Growl, Libnotify, or your
other notification framework of choice that you've broken things, or that
everything is still hunky-dorey and you should keep hacking away and/or ship!&lt;/p&gt;

&lt;p&gt;When I run tests manually I often want to run a single test, or set of tests
manually.  Using Rspec2 you can accomplish this with
&lt;a href="https://www.relishapp.com/rspec/rspec-core/docs/command-line/tag-option"&gt;tags&lt;/a&gt;
or calling the specific spec by line number via &lt;code&gt;bundle exec rspec &amp;lt;path to spec&amp;gt;:&amp;lt;line no. of spec to run&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Testing is not only a matter of making your tests all turn green.  Poorly
written tests can certainly be green and still not indicate that your code is
working as intended.  Perhaps you simply forgot to include any assertions  (I've
certainly never done that)  or you're testing your factories rather than your
models (never ever once again).  Code quality tools can help you with that as
well, and it's not entirely certain as to whether they fit in the "Red/Green"
phase of development, or in the "Refactor" phase.  I like to split the playing
field and say that code-coverage tools belong in the red/green phase as they
allow you to check the quality of your tests which firmly live in "red/green"
while other code quality tools (such as static analysis tools for cyclomatic
complexity) belong in the "Refactor" phase.  We've discussed code-coverage in Ruby
&lt;a href="http://highgroove.com/articles/2011/03/01/code-coverage-and-ruby-1-9.html"&gt;before&lt;/a&gt;
so have a look there for a refresher, but if you're not using one of these
tools it may be time to roll it into your workflow.  Cover-me even has a nice
post-test HTML coverage report to show you how well you've done.  This allows a
very tight development loop to make sure the tests are covering the right things
the first time.&lt;/p&gt;

&lt;p&gt;Tools to support steps 1 and 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing frameworks: &lt;a href="http://guides.rubyonrails.org/testing.html"&gt;MiniTest&lt;/a&gt;, &lt;a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/test/unit/rdoc/Test/Unit.html"&gt;Test::Unit&lt;/a&gt;, &lt;a href="https://github.com/rspec/rspec-rails"&gt;Rspec&lt;/a&gt;, &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sporkrb/spork"&gt;Spork&lt;/a&gt; and &lt;a href="https://github.com/guard/guard"&gt;Guard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Coverage tools: &lt;a href="https://github.com/markbates/cover_me"&gt;cover_me&lt;/a&gt;, &lt;a href="https://github.com/colszowka/simplecov"&gt;SimpleCov&lt;/a&gt;, &lt;a href="https://github.com/relevance/rcov"&gt;rcov&lt;/a&gt; (for Ruby 1.8 apps)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So you've got good tests, good test coverage, everything is green, and you're
ready to refactor.  If you are struggling to start your refactoring process then
either it's good enough as it is or maybe you need some inspiration.  Sometimes
your code just doesn't need to be refactored.  It is easy to fall into the
premature optimization problem and abstract/refactor/clean your way into a
corner that you will undoubtedly undo later when the customer asks for more or
different flexibility.  So maybe just delay refactoring if there isn't an
obvious need.  In the case of needing some hints as to where to refactor the
&lt;a href="http://rails-bestpractices.com/"&gt;Rails Best Practices&lt;/a&gt; site has you covered.&lt;/p&gt;

&lt;p&gt;There is no replacement for a good set of eyes on the code and intuition as to
where you can refactor.  To this end Highgroove's internal code reviews go a
long way to getting our code refactored quickly and elegantly.&lt;/p&gt;

&lt;p&gt;Since we are not constantly reviewing or pairing there are some tools to help us
along including the excellent Flog and Flay, a pair of tools to find complex
code and duplicate code, along with an interestingly macabre theme.  Another
tool is Excellent which produces warnings about "smelly code" via static
analysis.  Finally we have the big kahuna: Rails Code QA.  This package wraps up
other code quality packages (including Flog and Flay) to make a single rake task
that does it all.&lt;/p&gt;

&lt;p&gt;Tools to support step 3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ruby.sadi.st/Flog.html"&gt;Flog&lt;/a&gt; and
&lt;a href="http://ruby.sadi.st/Flay.html"&gt;Flay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://simplabs.github.com/excellent/"&gt;Excellent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nathanhumbert/rails_code_qa"&gt;Rails Code QA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;At this point you have your local code automatically being tested, you've run
the tests you need to focus on, you've refactored with the help of tools, the
rest of your development team, and the community's collective knowledge.  If you
are working on a feature branch, that branch needs to be merged into a staging
or production branch, and hopefully tested before being pushed to client or
customer facing environments.  This is where Continuous Integration (CI) comes
in.&lt;/p&gt;

&lt;p&gt;A CI environment is constantly running all of your tests on whatever branches it
needs to in order to make sure that any merge artifacts don't make their way into
production.  You may choose to run your own CI environment via Jenkins or
Goldberg, both of which are lightweight and well supported, or you may choose to
"outsource" your CI to a service.  Travis-CI has gotten a large following in the
Ruby community thanks to its super simple setup, integration with Github, and
quality service.  I was recently introduced to Tddium by a co-worker while
struggling to setup an internal CI system for a customer.  It looks very well
backed and supports pretty much all of the services we employ day to day.  If
you don't want to do operations to make sure your CI is up and running then
looking to one of the latter services is a great route.&lt;/p&gt;

&lt;p&gt;Tools to support step 4:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local CI tools: &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt;, &lt;a href="https://github.com/c42/goldberg"&gt;Goldberg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hosted services: &lt;a href="http://travis-ci.org/"&gt;Travis-CI&lt;/a&gt;, &lt;a href="https://www.tddium.com/"&gt;Tddium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Great! Your code is tested locally and in CI, everything looks solid in terms of
functionality, and Rails automagically does everything right for security.  It's
time to go ride bikes right?  Well maybe not.  There is a comprehensive and
excellent &lt;a href="http://guides.rubyonrails.org/security.html"&gt;Rails Security Guide&lt;/a&gt;
because it's not so simple.  This isn't to say that Rails security is as hard as
it could be, but as with everything getting it right requires knowing and
following the best practices created by the community.&lt;/p&gt;

&lt;p&gt;Luckily for us the Brakeman Scanner project integrates beautifully with the
tight testing workflow described above.  Brakeman is a static-analysis based
security-focussed scanner aimed at Rails applications.  It is under active
development and the progress has been phenomenal.  We did a brief
&lt;a href="http://highgroove.com/articles/2012/01/27/tech-talk-on-brakeman.html"&gt;tech-talk&lt;/a&gt;
about it recently and to say we are enamoured of it may be an understatement.
Even a couple of the bugs described in the tech-talk have been fixed since then!
Combining Brakeman's fantastic scanner and our automated testing tools works out
of the box in two ways.  Firstly there's Brakeman's reporting which is excellent
and could certainly be wrapped in a rake task to create a cover_me style report
after each test run.  Secondly there is guard-brakeman for local-scanning and
testing as well as notifications via your system notifier when new security
issues are introduced, just as if a test failed.  For CI environments Brakeman
works with Jenkins out of the box and adding support to other CI environments
should be a fairly simple operation.&lt;/p&gt;

&lt;p&gt;Tools to support step 5:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://brakemanscanner.org/"&gt;Brakeman&lt;/a&gt;, &lt;a href="https://github.com/oreoshake/guard-brakeman"&gt;Guard-Brakeman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Making your development and testing loop as tight as possible allows you to have
confidence that your code has been written in a process that promotes testing,
coverage, and automated quality tests so that you can focus on what's important:
shipping code and riding bikes.&lt;/p&gt;

&lt;p&gt;Tools to support step 6:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6059353268/" title="The @highgroove bike rack! by highgroove, on Flickr"&gt;&lt;img src="http://farm7.staticflickr.com/6072/6059353268_edaeefbf6c.jpg" width="500" height="374" alt="The @highgroove bike rack!"&gt;&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Kumbaya, My Award</title>
     <link href="http://highgroove.com/articles/2012/01/31/kumbaya-my-award.html" />
     <updated>2012-01-31T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/31/kumbaya-my-award.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6797358049"&gt;&lt;img
src="http://farm8.staticflickr.com/7002/6797358049_a788f6fb57_m.jpg"
style="float: right"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove, we love giving each other compliments. In fact, since
everyone at Highgroove kicks ass in some way, compliments are constantly
flying around (actually, I think that in and of itself was a compliment).&lt;/p&gt;

&lt;p&gt;Well-deserved compliments foster teamwork, increase morale, and make
us better as a team than we could be on our own.&lt;/p&gt;

&lt;p&gt;One specific way we compliment one another is by giving the &lt;a href="http://highgroove.com/faq.html#the-award"&gt;Highgroove
Award&lt;/a&gt;. The award can be given
by anyone to anyone; the recipient is recognized on the
&lt;a href="http://highgroove.com/about.html"&gt;website&lt;/a&gt; and with a &lt;a href="http://www.flickr.com/photos/highgroove/6797358049/in/photostream"&gt;physical
trophy&lt;/a&gt;
(it's a bit over the top on purpose!).&lt;/p&gt;

&lt;p&gt;Read on for how we added a technical twist to giving the award.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;




&lt;div style="float: right"&gt;
  &lt;a href="http://www.flickr.com/photos/highgroove/6797422435"&gt;&lt;img
  src="http://farm8.staticflickr.com/7170/6797422435_156cf93224_m.jpg"/&gt;
  &lt;/a&gt;

  &lt;div style="clear: both; height: 10px"&gt;&lt;/div&gt;

  &lt;a href="http://www.flickr.com/photos/highgroove/6797438193"&gt;&lt;img
  src="http://farm8.staticflickr.com/7161/6797438193_b6dd739a48_m.jpg"/&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Highgroove specializes in backend web application development, and while
some of the backends we develop actually drive mobile applications on iPhone, iPad, Android, and other mobile devices, we don't generally develop the frontends of these mobile applications in-house.&lt;/p&gt;

&lt;p&gt;Even so, a few of us are curious and wanted to learn more about how to
develop all aspects of mobile apps.  It helps us understand how to build better backends.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.flickr.com/photos/highgroove/6797422435/"&gt;Highgroove Award iPhone
App&lt;/a&gt; was born as a
recent weekend hack project.... And refined on a recent &lt;a href="http://highgroove.com/articles/2012/01/26/hack-night-at-highgroove.html"&gt;hack
night&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app allows any Highgroover to give the award via his or her iPhone.
A recipient is selected and the reasoning typed in; the backend portion
of the app redeploys the website with the new awardee!&lt;/p&gt;

&lt;p&gt;Now anyone can give the Highgroove Award ... even when we are
&lt;a href="http://www.flickr.com/photos/highgroove/6550928091/in/photostream"&gt;on-the-go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Highgroove Award is a bit silly, but it helps us give each other
serious praise in a light-hearted way. &lt;strong&gt;How does your workplace
encourage compliments?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aside: For a more detailed explanation of what goes into the backend and frontend of a mobile application, check out &lt;a href="http://kentnguyen.com/ios/what-does-it-take-to-make-an-ios-app/"&gt;Dear business people, an iOS app actually takes a lot of work!&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Great Office Rearrangement: Sit where you want</title>
     <link href="http://highgroove.com/articles/2012/01/27/the-great-office-rearrangement%3A-sit-where-you-want.html" />
     <updated>2012-01-27T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/27/the-great-office-rearrangement%3A-sit-where-you-want.html</id>
     <content type="html">&lt;p&gt;&lt;a href="https://twitter.com/#!/highgroove/status/134351062198009856/photo/1"&gt;&lt;img src="https://p.twimg.com/Ad1PlEoCQAAcU57.jpg:small" height="341" width="261" style="float: right"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove we are are always trying out new ways to improve our process and environment. One of my favorite experiments has been doing away with assigned seats. Our &lt;a href="http://www.gorowe.com"&gt;Results Only Work Environment&lt;/a&gt; allows each person to decide when and where they do their work. While it is true no one is required to come into the office, the reality is many people prefer to be in the office. It is not hard to see why. Every member of the team gets a massive monitor, a super comfy Aeron chair, and all the espresso and snacks anyone could ever need. Although most people come into the office regularly, each team member's hours can vary wildly. When we had assigned seats you could come in the office and be isolated just because your neighbors on a different schedule. Conversely, you could come in and be surrounded by a couple developers talking out a difficult problem when you really need to get something else done. In short, assigned seats just aren't very ROWE.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;h2&gt;The Setup&lt;/h2&gt;

&lt;p&gt;The fact that we hyper-specialize in back-end Ruby development means that everyone uses the same equipment and has basically the same needs. While this made doing away with assigned seats much easier than it would have been for a firm where there are many different types of specialized workers, we still had some issues to work out. First we had to deal with everyone's "desk stuff". If you have worked at a place with assigned seats you have probably noticed that you and your co-workers tend to "nest", building up a collection of trinkets, tools, and other things that may or may not be needed to get the job done. The amount of "desk stuff" has always been limited at Highgroove by small desks. Our work is done in the cloud using tools like Google Apps, &lt;a href="http://www.pivotaltracker.com"&gt;Pivotal Tracker&lt;/a&gt; and &lt;a href="http://www.github.com"&gt;Github&lt;/a&gt;. We generally don't need desk space for much more than a keyboard, mouse, snacks and maybe a latte. If the desk is holding much else, chances are that stuff is in the wrong place. If the "desk stuff" is information you or your team members need and exist nowhere else, you are working in a silo. That is bad. If the "desk stuff" is something not related your current tasks, it is clutter: a distraction at best, it should be elsewhere. Where do we put all this stuff? We have a cubby section where each developer can safely store their stuff like bike clothes, business cards, notebooks, and other things we use but don't need constantly to do our work. We also use cubbies to store our keyboards and mice when we leave, so that others can use the vacant desks.&lt;/p&gt;

&lt;p&gt;Cubbies were about the only addition we needed to make this work. We provide everyone on the team with the best equipment available, so there is no inequality; no good desk or chairs to fight over. If you were implement this policy in an office where there were several different types of desks and chairs you would want to make sure there are enough setups of each type to make everyone happy.&lt;/p&gt;

&lt;h2&gt;The Results&lt;/h2&gt;

&lt;p&gt;We've been running this experiment for several months now. The no assigned seats policy allows everyone the chance to switch things up and get to know each other better. The policy also allows team members to have more control over their environment. When there are a lot of people in the office, desk selection can be slim, but so far no one has been without a desk, or has vocally complained about having to sit at a desk they don't want to. Some people still sit in the same desk everyday. Other people sit at a different desk every time they come into the office. The point of ROWE is that we are all responsible adults, perfectly capable of making our own decisions. We decide when it is time to work and time to play. The next logical step was to remove assigned seating for those who decide to work in our office. Doing so has given each member of our team the more control over their work environment, and has also made for a more open and collaborative workplace. What steps have your team taken to make your office more awesome for everyone?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Talk on Brakeman</title>
     <link href="http://highgroove.com/articles/2012/01/27/tech-talk-on-brakeman.html" />
     <updated>2012-01-27T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/27/tech-talk-on-brakeman.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/fishywang/231641679/" title="Bicycle locks by Yuxuan.fishy.Wang, on Flickr"&gt;&lt;img src="http://farm1.staticflickr.com/80/231641679_316877d9b6_m.jpg" width="240" height="180" alt="Bicycle locks" align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dave's Tech Talk this week is on security on web applications, focusing on Ruby on Rails applications, and using the static analysis security scanner called &lt;a href="http://brakemanscanner.org/"&gt;Brakeman&lt;/a&gt; (&lt;a href="https://github.com/presidentbeef/brakeman"&gt;brakeman on github&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In this talk, Dave looks at how static security analyzers work, and how we used it to find some very tiny (already fixed within a few minutes of finding) possible security weak-points in an application we built for a client.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Static analysis looks at your source code and looks for known vulnerabilities.  As opposed to dynamic scanners, or intrusion "detection" scanners that scan a live site from the outside -- these are run on the code itself.&lt;/p&gt;

&lt;p&gt;In Ruby this is hard because it's a dynamic language.  Because of this, Brakeman (and any static analysis scanners) will identify "false positives" (code that isn't necessarily a vulnerability) but they're easy to track down, and safely ignore.&lt;/p&gt;

&lt;p&gt;Dave notes, that because of Ruby's dynamic-ness, if you are doing a lot of method_missing meta-programming, it won't be able to analyze your code.  The practices and places it does identify are easy to see, and you can apply Brakeman's other recommendations in your meta-programming code, to secure your web application.&lt;/p&gt;

&lt;p&gt;Check out the talk on Vimeo: &lt;a href="http://vimeo.com/35766582"&gt;Tech Talk on Brakeman&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image Credit: &lt;a href="http://www.flickr.com/photos/fishywang/231641679/"&gt;fishywang on Flickr&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Hack Night at Highgroove</title>
     <link href="http://highgroove.com/articles/2012/01/26/hack-night-at-highgroove.html" />
     <updated>2012-01-26T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/26/hack-night-at-highgroove.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6768143749/" title="Hack Night! Twitter bots, io language, iPad apps, gaming in c#.... by highgroove, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7017/6768143749_1615ae7e03_m.jpg" width="240" height="180" alt="Hack Night! Twitter bots, io language, iPad apps, gaming in c#...."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Highgroove hosted our monthly Hack Night, and with 20 attendees, this was our largest yet.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;To program a computer in a clever, virtuosic, and wizardly manner. Ordinary computer jockeys merely write programs; hacking is the domain of digital poets. Hacking is a subtle and arguably mystical art, equal parts wit and technical ability, that is rarely appreciated by non-hackers. See hacker. -- &lt;a href="http://www.urbandictionary.com/define.php?term=hack"&gt;Urban Dictionary: hack&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Hack Nights are a chance for Highgroovers to simply "hack" which means: to experiment, learn, and play with technologies we might not get to during our day-to-day.  So, what did we hack on?&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;ul&gt;
&lt;li&gt;the &lt;a href="http://iolanguage.com/"&gt;io language&lt;/a&gt; using Day 1 of the io chapter in the &lt;a href="http://pragprog.com/book/btlang/seven-languages-in-seven-weeks"&gt;Seven Languages in Seven Weeks&lt;/a&gt; book&lt;/li&gt;
&lt;li&gt;game programming (the wolfbrain) on the &lt;a href="https://www.sifteo.com/"&gt;Sifteo Game Cubes&lt;/a&gt; in C#&lt;/li&gt;
&lt;li&gt;a remote music playing server with voting and control from our chat room for the office&lt;/li&gt;
&lt;li&gt;adding functionality to some of our favorite ruby gems and libraries including &lt;a href="https://github.com/presidentbeef/brakeman"&gt;brakeman&lt;/a&gt;, and a yet-unreleased crazy-math backend algorithm solver&lt;/li&gt;
&lt;li&gt;an iOS app for awarding Highgroovers the coveted &lt;a href="http://highgroove.com/faq.html#the-award"&gt;Highgroove Award&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a search-across-the-company app using some new search technologies powered by Ruby&lt;/li&gt;
&lt;li&gt;and much, much more....&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Thanks to all who came out. Stay tuned for our next Hack Night in February by liking us on &lt;a href="http://facebook.com/highgroove"&gt;Facebook&lt;/a&gt; and &lt;a href="http://twitter.com/highgroove"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Maintaining Clients (keeping everyone happy)</title>
     <link href="http://highgroove.com/articles/2012/01/24/maintaining-clients-%28keeping-everyone-happy%29.html" />
     <updated>2012-01-24T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/24/maintaining-clients-%28keeping-everyone-happy%29.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/madlyinlovewithlife/6030999896/lightbox/"&gt;&lt;img src="http://farm7.staticflickr.com/6206/6030999896_25c3a9ac18.jpg" align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Far too often there exists a chasm between the client paying for and the developer working on a particular project.  One party has a longterm vision; a vision that will ultimately impact his/her financial future.  The other party has a much closer view of the project, which creates the risk of getting tunnel visioned. The client worries about when the project will be completed; the developer worries about how the project will be completed.  When this happens, communication becomes difficult and frustration builds. How can this be avoided?&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;At Highgroove, we know that there is no replacement for good communication. This perhaps requires a bit more work from our clients than they might initially anticipate, but by maintaining frequent contact, we prevent frustration and confusion from creeping into the process. By keeping our clients actively involved (i.e. forcing them to accept/reject stories in Pivotal Tracker), they know exactly where the project stands and what work remains. This helps the project stay on track and gives us, the developers, quick feedback about whether or not the work being done is acceptable.&lt;/p&gt;

&lt;p&gt;When we are able to maintain this level of communication with our clients, we can develop a comfortable working relationship that allows us to honestly question features or approaches that would complicate projects and potentially delay launching. At Highgroove, we earnestly want our clients' projects to succeed. We hope that our clients choose us not for only our technical skill, but our dedication to giving them the best version of their vision.  By striving to cultivate a successful working relationship, we go beyond maintaining happy clients: we promote successful enterprises.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Talk on Riak</title>
     <link href="http://highgroove.com/articles/2012/01/20/tech-talk-on-riak.html" />
     <updated>2012-01-20T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/20/tech-talk-on-riak.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://instagr.am/p/i50I-/"&gt;&lt;img src="http://distilleryimage6.instagram.com/96403754439a11e1abb01231381b65e3_7.jpg" align="right" height="200" width="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Will's Tech Talk this week is on Riak.  "Riak is an open source, highly scalable, fault-tolerant distributed database." -- &lt;a href="http://basho.com/products/riak-overview/"&gt;Riak Overview on Basho.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main use-case is to use in web applications that have heavy requirements for data, where lots of data must be "written" or "read" in a distributed fashion, but needs to be high-availability.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Will also went over one of the main Ruby libraries named &lt;a href="https://github.com/seancribbs/ripple"&gt;ripple&lt;/a&gt; that is a rich Ruby modeling layer for Riak, Basho's distributed database that contains an ActiveModel-based document abstraction.&lt;/p&gt;

&lt;p&gt;Riak works great when your database gets painful.  If you have an application that just has tons of writes, or tons of reads happening, and the database is just dragging, Riak is a great choice for storing and reading data quickly.  Adding Riak along-side your database to alleviate performance is a great way to scale out and make your web application more performant.&lt;/p&gt;

&lt;p&gt;Check out the video on our Tech Talks page:  &lt;a href="http://vimeo.com/highgroove/videos"&gt;http://vimeo.com/highgroove/videos&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Git Treeishes Considered Awesome</title>
     <link href="http://highgroove.com/articles/2012/01/19/git-treeishes-considered-awesome.html" />
     <updated>2012-01-19T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/19/git-treeishes-considered-awesome.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/moonlightbulb/3338852116/" title="A Street Called Awesome by moonlightbulb, on Flickr"&gt;&lt;img src="http://farm4.staticflickr.com/3574/3338852116_e06a7a111f.jpg" width="500" height="375" style="float: right;" alt="A Street Called Awesome"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As developers, we love having quality tools like &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt;, available to us.&lt;/p&gt;

&lt;p&gt;Using git, we can easily navigate through all the code ever "committed" or added to a project throughout its history. We do this via git  &lt;a href="http://book.git-scm.com/4_git_treeishes.html"&gt;treeishes&lt;/a&gt;.
Treeishes are git's way of referencing commits and relations between commits.
Treeishes can improve your workflow immensely if you're a frequent git user.&lt;/p&gt;

&lt;p&gt;In this post, we'll cover some of the more basic treeishes and then
work into the advanced ones, with some real-world examples.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;




&lt;h2&gt;The Basics&lt;/h2&gt;


&lt;p&gt;You'll probably be familiar
with the types of treeishes in this first section if you've ever used git
before. The following section will cover some more advanced uses of
treeishes that even long-time git users may not know about.&lt;/p&gt;

&lt;h3&gt;SHAs&lt;/h3&gt;


&lt;p&gt;Every commit in git is identified by its SHA — a unique hash. These hashes
are pretty long (40 characters in fact), but git also allows you to
reference any commit with &lt;em&gt;any&lt;/em&gt; truncated version of its hash so long
as the truncated portion is unique (generally, this means at least 5
characters long).&lt;/p&gt;

&lt;h3&gt;Branches, Remotes, and Tags&lt;/h3&gt;


&lt;p&gt;Branches, remotes, and tags are another kind of treeish. Each of these
is actually just a pointer to a git commit.&lt;/p&gt;

&lt;h2&gt;Advanced Treeishes&lt;/h2&gt;


&lt;p&gt;Now we're getting to the really good stuff!&lt;/p&gt;

&lt;p&gt;It's important to have a good understand of the git reference log
(reflog for short) which enables most of the more advanced treeishes.&lt;/p&gt;

&lt;p&gt;The git reflog is a running log of recent changes to tips of branches.
In practice, this means that every time you commit to a branch, pull
commits down from a remote repository, or checkout a new branch, your
reflog will update. It's important to recall that reflogs are specific
to individual checkouts of a repository so the reflogs for the same
project can differ across machines.&lt;/p&gt;

&lt;p&gt;Here's an example reflog from one of my personal projects:&lt;/p&gt;

&lt;script src="https://gist.github.com/1609626.js?file=git%20reflog"&gt;&lt;/script&gt;


&lt;p&gt;This reflog shows that some of the more recent changes to this project include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloning the project from the remote repository&lt;/li&gt;
&lt;li&gt;Making a few commits&lt;/li&gt;
&lt;li&gt;Checking out a new branch from the tree at &lt;code&gt;0a4faaa&lt;/code&gt; (which just happens to be &lt;code&gt;master&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Using the reflog, git can infer some interesting relative context for commits
that will allow us some more flexibility in what we can get at with treeishes.&lt;/p&gt;

&lt;h3&gt;Date Specs&lt;/h3&gt;


&lt;p&gt;We use the date spec here at Highgroove as part of our weekly code reviews.
With the date spec, I can easily look at the activity on a feature branch over
the course of the last week:&lt;/p&gt;

&lt;script src="https://gist.github.com/1609626.js?file=git%20date%20spec"&gt;&lt;/script&gt;




&lt;h3&gt;Tilde Spec&lt;/h3&gt;


&lt;p&gt;Similar to the ordinal spec, the tilde spec allows you to reference
the Nth grandparent of a commit.&lt;/p&gt;

&lt;p&gt;This is useful just to go back 2 or more commits in time in one command.&lt;/p&gt;

&lt;script src="https://gist.github.com/1609626.js?file=git%20tilde%20spec"&gt;&lt;/script&gt;




&lt;h3&gt;Caret Parent Spec&lt;/h3&gt;


&lt;p&gt;Unlike the tilde spec, the caret parent spec allows you to
reference the Nth parent of a commit. The distinction here
is important as the caret parent spec can walk backwards
through commits that have more than one parent (merge commits),
while the ordinal spec cannot.&lt;/p&gt;

&lt;p&gt;The caret parent spec looks like:&lt;/p&gt;

&lt;script src="https://gist.github.com/1609626.js?file=git%20caret%20parent%20spec"&gt;&lt;/script&gt;


&lt;p&gt;The caret parent spec and the tilde spec can also be chained together,
so &lt;code&gt;master^^&lt;/code&gt; would actually point to the same commit as &lt;code&gt;master~2&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Range Spec&lt;/h3&gt;


&lt;p&gt;The range spec allows you to express a range of commits as a first-class
object in git. These are frequently used for things like diffs where
you may want to view the changes across a number of commits.&lt;/p&gt;

&lt;p&gt;For example, the following command would show a diff of all commits
between master and my current feature branch:&lt;/p&gt;

&lt;script src="https://gist.github.com/1609626.js?file=git%20range%20spec"&gt;&lt;/script&gt;


&lt;p&gt;You can also refer to the range from the current commit through
all commits after it by just leaving off the other ref after
the "..".&lt;/p&gt;

&lt;p&gt;All of these treeishes are available from the git command line
interface -- though if you're using a GUI to interact with git your
particular application it may support some or all of these.
I know that Github's &lt;a href="https://github.com/blog/612-introducing-github-compare-view"&gt;compare view&lt;/a&gt;
can be used with treeishes as well. Hopefully if you're not
already using treeishes you'll find that they're as useful
to you as they are to us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How are you using git treeishes to improve your workflow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Image credit: &lt;a href="http://www.flickr.com/photos/moonlightbulb/3338852116/"&gt;@moonlightbulb&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Simple Design, the Highgroove Way</title>
     <link href="http://highgroove.com/articles/2012/01/16/simple-design%2C-the-highgroove-way.html" />
     <updated>2012-01-16T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/16/simple-design%2C-the-highgroove-way.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/File:Mondrian_Composition_II_in_Red,_Blue,_and_Yellow.jpg"&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/en/f/fe/Mondrian_Composition_II_in_Red%2C_Blue%2C_and_Yellow.jpg" style="float: right" height="200" width="200"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Highgroove Studios has taught me a lot about Software Development, Consulting, and building new web applications.  Apart from the myriad of technical skills I've added since I came on board, Highgroove is a fantastic company to learn how to build your own web apps, how to design them, and how to remain focused on the most business critical aspects of the system.  Highgroove taught me these things by adhering to a process which manages Agile development, responds to changing software requirements and business needs, and encourages constant communication.  While these are all noticed by clients, there is one part of the Highgroove process that goes largely unseen; however, it is just as integral as the former three.  That behind-the-scenes aspect of the Highgroove development process is keeping the software as simple as possible to meet current demands.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Keeping software systems simple is fundamental to the development style at Highgroove.  What I've seen a lot of developers do (not the Highgroove developers of course!) is create an application that is too complex for the current applications scope, which wastes precious time in the process.  The unfortunate side effect of creating apps that are too complex for what is actually needed is ultimately an app that performs poorly under load, is prone to errors, and is very difficult to change.  All of those things affect a projects budget and could have been avoided.  At Highgroove, we leverage the Open Source community and Ruby on Rails to build scalable web applications.  This web application development framework comes with a core set of plugins but also enjoys a host of plugins and libraries all available for free.  We don't write custom loggers.  We don't write google apps or Facebook authentication from scratch.  We hardly even have to write SQL.  We leverage the network of freely available, well tested and trusted plugin library to accomplish these basic tasks for us.  Once the common system functions are handled, that allows Highgroove to focus solely on business logic and building the app.  That really means we get more done, in less time, and on budget too!&lt;/p&gt;

&lt;p&gt;At Highgroove, we do not believe in creating &lt;a href="http://en.wikipedia.org/wiki/Rube_Goldberg_machine"&gt;Rube Goldberg machines&lt;/a&gt;…we just want to build the best possible app with the least amount of complexity that does exactly what you need.  Its because of this ethos that Highgroove's customers succeed (and I grow as a developer and a consultant too!).&lt;/p&gt;

&lt;p&gt;How do you build apps?&lt;/p&gt;

&lt;p&gt;Image Credit: &lt;a href="http://en.wikipedia.org/wiki/File:Mondrian_Composition_II_in_Red,_Blue,_and_Yellow.jpg"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Getting into the Groove</title>
     <link href="http://highgroove.com/articles/2012/01/16/getting-in-the-groove.html" />
     <updated>2012-01-16T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/16/getting-in-the-groove.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/navart/4691826742/" title="Comando Groovy @ 2º Aniversario Radio Mexiquense 91.7 FM by navart, on Flickr"&gt;&lt;img src="http://farm5.staticflickr.com/4007/4691826742_cd8097b3f6.jpg" width="500" height="375" alt="Comando Groovy @ 2º Aniversario Radio Mexiquense 91.7 FM" style="float: right;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going in to my third week here at Highgroove, I already feel like my
first couple weeks have been some of my best in any work environment,
both in terms of my personal productivity and my happiness at work.&lt;/p&gt;

&lt;p&gt;I'm still completing my undergraduate degree at &lt;a href="http://www.gatech.edu/"&gt;Georgia Tech&lt;/a&gt;.
As any student at Tech will be quick to tell you, the school is often
very demanding of its students. This can often make a good balance
between work and school difficult, and juggling the two over the past
couple years of school has been challening.&lt;/p&gt;

&lt;p&gt;Enter Highgroove, a ROWE (Results-Only Work Environment).&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;I've been lucky enough to call a good portion of the Highgroove staff
friends for a while, and I'd known that Highgroove works on amazing
projects with even more amazing clients. This was more than enough
to get me excited to work with Highgroove. But hearing more about
how Highgroove is a ROWE during my interview process really interested me.&lt;/p&gt;

&lt;p&gt;A ROWE sounds pretty self-explanatory — it's all about results. Focusing
on results rather than time spent "working" (who hasn't checked on Reddit
at work before?), allows us to work in a fashion that's all about personal
responsibility and trust. I can take a day to study for a big exam if I know
I'll have some time later on in the iteration to make sure I'm hitting my
results. Reading the &lt;a href="http://www.amazon.com/Why-Work-Sucks-How-Fix/dp/1591842921/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1292244800&amp;amp;sr=1-1"&gt;ROWE book&lt;/a&gt;
(ironically, the one requirement we have at Highgroove besides meeting results)
and working in a ROWE has already taught me a lot: mostly I don't think
I could go back to working any other way.&lt;/p&gt;

&lt;p&gt;Highgroove gives me control over my time and allows me to focus on getting
things done — whether for work, school, or me — in a completely guilt-free
environment. And I'm loving every minute of it.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Using MySQL Spatial Extensions for Range Queries</title>
     <link href="http://highgroove.com/articles/2012/01/10/using-mysql-spatial-extensions-for-range-queries.html" />
     <updated>2012-01-10T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/10/using-mysql-spatial-extensions-for-range-queries.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/nnova/3399904953/sizes/s/in/photostream/"&gt;&lt;img src="http://farm4.staticflickr.com/3603/3399904953_3f2c06c943_m.jpg" style="float: right"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We help one of our clients operate a high traffic API that, among other
things, returns data that is associated with an IP address range. It's
similar to querying for information from &lt;a href="http://en.wikipedia.org/wiki/WHOIS"&gt;WHOIS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The IP address ranges are specified in a MySQL database with &lt;strong&gt;ip_start&lt;/strong&gt; and
&lt;strong&gt;ip_end&lt;/strong&gt; columns. The IP addresses are first converted to their
representation as 32-bit integers.&lt;/p&gt;

&lt;p&gt;For instance, the range 1.1.1.1 to 1.1.3.3 would look like:&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;ip_start&lt;/th&gt;
    &lt;th&gt;ip_end&lt;/th&gt;
    &lt;th&gt;...&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;16843009&lt;/td&gt;
    &lt;td&gt;16843523&lt;/td&gt;
    &lt;td&gt;...&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Read on for more about how we helped optimize the queries that search
for an IP within these ranges.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Loading new information into the API required that we test whether a new
IP range overlapped with a current range in the database.&lt;/p&gt;

&lt;p&gt;It is relatively easy to &lt;a href="http://c2.com/cgi/wiki?TestIfDateRangesOverlap"&gt;write a query that tests whether one range
intersects another in SQL&lt;/a&gt;:&lt;/p&gt;

&lt;script src="https://gist.github.com/1593170.js?file=range.sql"&gt;&lt;/script&gt;


&lt;p&gt;Unfortunately, even with indexes, this query requires a full table scan
in MySQL. On a large table, the query took around 0.25 seconds. While
insignificant for one-off queries, loading thousands of new ranges made
the time really add up.&lt;/p&gt;

&lt;p&gt;We scoped out various solutions, but the one that ended up working best
was modeling the problem using &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/spatial-extensions.html"&gt;MySQL Spatial
Extensions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While IP ranges are not a typical use case for spatial extensions, they
can be modeled as 1-dimensional lines. And given that spatial indexes
are very efficient at doing queries like
&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/functions-for-testing-spatial-relations-between-geometric-objects.html#function_intersects"&gt;Intersects()&lt;/a&gt;,
we found the solution to be really performant.&lt;/p&gt;

&lt;p&gt;The following SQL snippet creates a column called &lt;strong&gt;ip_range&lt;/strong&gt; on the
table that is then populated with rectangles in 2-dimensions that
represent the IP ranges. We only care about 1-dimension, so the height
of the rectangles is unimportant:&lt;/p&gt;

&lt;script src="https://gist.github.com/1593170.js?file=create_geometry.sql"&gt;&lt;/script&gt;


&lt;p&gt;With that column and the spatial index, queries to test for range
intersection can be written as:&lt;/p&gt;

&lt;script src="https://gist.github.com/1593170.js?file=range_spatial.sql"&gt;&lt;/script&gt;


&lt;p&gt;This query achieves the same thing as the earlier query, but runs much
faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you modeled a problem with the geospatial features of a database?&lt;/strong&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Hadoop Across Availability Zones</title>
     <link href="http://highgroove.com/articles/2012/01/10/hadoop-across-availability-zones.html" />
     <updated>2012-01-10T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/10/hadoop-across-availability-zones.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20120111-dwgtmswx5nx8yax1tmy22a74yw.jpg" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;Hadoop is a great solution to the big data problem and with the instant access to servers and storage in the cloud, it's easier than ever to spin up and manage your own cluster. If you haven't heard too much about it yet, &lt;a href="http://wiki.apache.org/hadoop/"&gt;hadoop&lt;/a&gt; provides access to a distributed file system along with a framework for running map reduce jobs over the data. It takes care of replicating chunks of data to each node and running jobs in parallel for you. However, when you want to expand your hadoop cluster across availability zones you can run into some unexpected problems. So lets dig into the ideas we tried and the final solution that worked the best for our configuration.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Communicating across data centers is a pretty old problem with a lot of different solutions so we wanted to start out with the simplest thing we could think of. First, we decided to allow access by adding an elastic ip to each node and adding those addresses in the security group of the opposite availability zone. So this would basically just allow open communication from certain public addresses on the internet, which isn't a bad solution. But if you ever need to replace or spin up a new node, it requires a decent bit of manual intervention to reassign the elastic ip or to create a new one and add it back to the security groups. Another downside is that, due to hadoop's fancy hostname resolution, we can only utilize tasktrackers within the same availability zone as the namenode.&lt;/p&gt;

&lt;p&gt;So next we tried using OpenVPN to create a bridge across the two networks, but there was one small problem. Because we didn't have full control over what ip address our servers were assigned, there was the potential for two machines with the same ip on separate networks which would cause all kinds of weird problems. &lt;a href="http://aws.amazon.com/vpc/"&gt;Amazon's VPC&lt;/a&gt; can help solve this problem by giving you more control over the network but we decided to go a different route.&lt;/p&gt;

&lt;p&gt;Instead of using a classic VPN solution, we gave &lt;a href="http://tinc-vpn.org"&gt;tinc&lt;/a&gt; a try. Tinc is still considered a vpn daemon but instead of using it for a point to point connection, because it is so lightweight, you can install it on all of your servers and expose a new network interface to route traffic over. This allowed us to easily configure the vpn on the production system and then just switch the interface hadoop was listening on once everything was up and running. So here's how we set it up.&lt;/p&gt;

&lt;p&gt;Three files make up the basic configuration. The tinc-up script is responsible for creating the new network interface. The tinc.conf names the local node and keeps track of all the other nodes it needs to talk to. We also need a hosts file which is named after the local node we set in the tinc.conf. This file includes attributes for setting up the connection to the vpn like the external ip, vpn ip, vpn subnet and public key. Since we have everything already set up in chef we just set up a cookbook that ran a few searches across our servers and generated all the configuration files we needed. We also took advantage of hadoop's rack awareness feature to make sure data is always streamed from the closest node and also makes sure replicas are spread across different data centers. There was only 1 problem that we came across which again involved hadoop's hostname resolution. Map reduce jobs were periodically failing because the tasktracker would sometimes use the ec2 hostname and resolve the ip of a datanode incorrectly. So, we had to setup a tiny dns server to make sure that hostnames always pointed to correct tinc address. After fixing that everything worked great. We also had the added benefit of being able to connect through the vpn and access the files from hdfs directly using &lt;a href="http://cloudera.github.com/hue/"&gt;hue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since we quickly covered a lot of new technology, here are some useful resources for when you want to try this out yourself:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://wiki.apache.org/hadoop/"&gt;Hadoop Wiki&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://github.com/opscode/cookbooks/tree/master/hadoop"&gt;Hadoop Chef Cookbook&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://tinc-vpn.org/documentation/tinc_toc"&gt;Offical Tinc Manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.vanheusden.com/Linux/tinc_mini_howto.html"&gt;Quick Tinc Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://reiddraper.com/first-chef-recipe/"&gt;Writing Your First Chef Recipe&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://hadoop.apache.org/common/docs/stable/cluster_setup.html#Hadoop+Rack+Awareness"&gt;Hadoop Rack Awareness&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://thekelleys.org.uk/dnsmasq/doc.html"&gt;Dnsmasq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;What other tips do you have on breaking the single availability zone barrier?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Demo on RescueTime</title>
     <link href="http://highgroove.com/articles/2012/01/06/tech-demo-on-rescuetime.html" />
     <updated>2012-01-06T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/06/tech-demo-on-rescuetime.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6648460323/" title="Tech Demo on @rescuetime - personal analytics on your productivity. by highgroove, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7018/6648460323_f78e7fab17_m.jpg" width="240" height="180" alt="Tech Demo on @rescuetime - personal analytics on your productivity." align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://highgroove.com/stafford.html"&gt;Stafford&lt;/a&gt; is demoing on productivity hacking with &lt;a href="https://www.rescuetime.com/"&gt;RescueTime&lt;/a&gt;.  "It's like server analytics for you and your time," says Stafford.&lt;/p&gt;

&lt;p&gt;We all like to think of ourselves as productive, but we can all use some help being more efficient.  One tool Stafford likes using is RescueTime that tracks where you're spending your time while using your computer.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;RescueTime runs in the background, and tracks applications that are open.  It then tries to help you classify which applications are productive and which are non-productive.  It can show you how much time you're spending browsing Facebook, versus writing code.  You can even help it learn which tasks for you are more productive -- for some people, email is productive, for others, maybe not.&lt;/p&gt;

&lt;p&gt;There are some very cool charts that show where time is spent, in your browser, in your code editor, in your email client, etc.  It can show you when you're most productive, just by knowing.  It also has a competition aspect, you can see how your productivity numbers stack against others, and even yourself each week.&lt;/p&gt;

&lt;p&gt;Stafford goes in once a day to clean up his RescueTime and reclassify events like: "Chatting" which may be with a client, or with a friend.&lt;/p&gt;

&lt;p&gt;Stafford also showed off the project view, which helps him realize what tasks he's worked on for a client/project.&lt;/p&gt;

&lt;p&gt;Stafford ended saying: "It's a good gauge of when I'm being productive.  If I'm not being productive, it's time to leave and get away, go do something else, and come back when I'm productive to work."&lt;/p&gt;

&lt;p&gt;Check out the video on our &lt;a href="http://vimeo.com/highgroove"&gt;Vimeo&lt;/a&gt; channel, in our Tech Talks.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Accept/Reject as you go!</title>
     <link href="http://highgroove.com/articles/2012/01/04/accept-reject-as-you-go%21.html" />
     <updated>2012-01-04T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/04/accept-reject-as-you-go%21.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.toothpastefordinner.com/" target="_blank"&gt;
&lt;img src="https://img.skitch.com/20120104-nn5cntwaa2yubdgxhe6cgs188f.jpg" width="300" height="221" border="0" style="border:none;" alt="Via http://www.toothpastefordinner.com/" /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove, we like forward momentum.  This means that we know that every delivery cannot be perfect, so instead of worrying about perfection, we worry about progress.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;By tracking stories in &lt;a href="https://www.pivotaltracker.com/dashboard" target="_blank"&gt;Pivotal Tracker&lt;/a&gt;, we have an easy interface to shoot stories back and forth with our clients.  As each story is delivered, the client can either accept or reject it.  Acceptance allows us to move on to other stories; rejection requires us to restart the story.&lt;/p&gt;

&lt;p&gt;But unlike in some other situations, this rejection does not send us crying into a bathroom stall, diary in hand.  In fact, this rejection simply helps refine what the story should actually accomplish.&lt;/p&gt;

&lt;p&gt;Sometimes clients seem a bit hesitant to reject a story, opting to instead leave a comment that informs us that while they expected to send an email when they clicked "send email," the system actually logged them out of the site completely.  Then the client will proceed to accept the story based on the fact that the button did in fact do something.  This helps no one!  Reject this!&lt;/p&gt;

&lt;p&gt;The constant feedback of accept/reject keeps a developer on track and on pace.  When we are waiting for feedback on prior stories, the stories we work on in the meantime lack certainty.  We depend on the process to produce and progress.&lt;/p&gt;

&lt;p&gt;Acceptance feels great! ...when it is for the right reasons.  But the important part is not whether you check "yes" or "no" but that you send the note back before class ends!&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Using Git Hunks</title>
     <link href="http://highgroove.com/articles/2012/01/02/using-git-hunks.html" />
     <updated>2012-01-02T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2012/01/02/using-git-hunks.html</id>
     <content type="html">&lt;p&gt;As a developer, I always try to follow the "Boy Scout Principle" when it comes to the code I'm working with. Simply put:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;always leave the code cleaner than when you found it&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;based on the idea that Boy Scouts always leave a campground cleaner than when they found it.&lt;/p&gt;

&lt;p&gt;It is tempting to make sweeping changes and clean up lots of code while  implementing a small new feature, however, it's also good practice to separate  commits that don't include any unrelated changes. Occasionally this means that a file that has a few small changes that clean up code, and others that are dealing with some functional changes, needs to get committed. Luckily, git has an awesome feature that allows us to get exactly what we want: hunks.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;&lt;a href="http://www.harkavagrant.com/index.php?id=330"&gt;&lt;img src="https://img.skitch.com/20120102-ksgjjrmdqgtmdmijkkkdcyus3c.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many of the git subcommands can be passed &lt;code&gt;--patch&lt;/code&gt; or &lt;code&gt;-p&lt;/code&gt; for short. When used
with &lt;code&gt;git add&lt;/code&gt;, we can compose a commit with exactly the changes we want,
instead of just adding whole files. Once you hit enter, you get an interactive
prompt where you're presented with a diff and a set of options.&lt;/p&gt;

&lt;script src="https://gist.github.com/1551480.js?file=gistfile1.txt"&gt;&lt;/script&gt;


&lt;p&gt;Some of the more important options are y (yes), n (no), q (quit), and s for
"split into smaller hunks". Using this we can easily create a commit with only
the changes I made to clean up a file, instead of any other changes I made.
When this isn't enough, you can also use e (edit) which will open &lt;code&gt;$EDITOR&lt;/code&gt; and
allow you to modify your diff and get it just right. Once you save, git will
make sure that it still applies to the files you're editing.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;git add -p&lt;/code&gt; allows us to make nice small self-contained commits that only
change 1 thing at a time. However, we can use hunks in other places too. &lt;code&gt;git
reset -p&lt;/code&gt; will allow us to do the exact opposite and unstage things we don't
want to commit by hunk. We can also use it with &lt;code&gt;git checkout&lt;/code&gt; to completely get
rid of changes we don't want and may have accidentally added.&lt;/p&gt;

&lt;p&gt;This small feature changed how I work, allowing me to crank through a bunch of
code and then go back and compose good commits. Are there any small git features
that you really enjoy?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Using Block Scope for a Fancy DSL</title>
     <link href="http://highgroove.com/articles/2011/12/30/using-block-scope-for-a-fancy-dsl.html" />
     <updated>2011-12-30T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/30/using-block-scope-for-a-fancy-dsl.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20111230-drdytgg7sicrurfibseahi1762.jpg"&gt;&lt;/p&gt;

&lt;p&gt;In Ruby, blocks are kind of a big deal. We use them for everything from basic
iteration to executing callbacks. They are also really handy for writing
&lt;a href="http://www.jroller.com/rolsen/entry/building%5Fa%5Fdsl%5Fin%5Fruby"&gt;Domain Specific Languages&lt;/a&gt;,
or DSLs for short. For example, checkout how &lt;a href="https://github.com/sprsquish/blather"&gt;blather&lt;/a&gt;
uses blocks to respond to an XMPP message.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;




&lt;script src="https://gist.github.com/1540434.js?file=message_example.rb"&gt;&lt;/script&gt;


&lt;p&gt;We call the message method with some options and a block to execute when a
message with those options is received. Blocks make this code a lot more fun
to write because the event handler is hooked up behind the scenes. All we
really have to worry about is what happens when we receive a specific message.
So how would we implement this?&lt;/p&gt;

&lt;script src="https://gist.github.com/1540525.js?file=message_implementation.rb"&gt;&lt;/script&gt;


&lt;p&gt;Without including the extra boiler plate to actually receive messages, it's
pretty simple code. We just register a callback and call it when the event
happens. But, I want to take this a step further. If you've used &lt;a href="https://github.com/sinatra/sinatra"&gt;sinatra&lt;/a&gt;,
these examples involving blocks should look pretty familiar. Here's an example
of a simple get request definition to refresh your memory.&lt;/p&gt;

&lt;script src="https://gist.github.com/1540557.js?file=get_request_example.rb"&gt;&lt;/script&gt;


&lt;p&gt;Cool! But how is this different from the blather message example? Look at the
block we passed in. Notice anything different? We didn't pass any parameters
to the callback, but we used a params variable to get the beverage for the
request. We never defined it in the scope before the block in our code. So,
where did it come from? Since we always want to have a params hash in the
callback of a request it makes sense that it would already be defined for us,
but sinatra is actually doing some interesting things behind the scenes to make
this happen. Let's look at another example of how we would implement this DSL.&lt;/p&gt;

&lt;script src="https://gist.github.com/1540671.js?file=get_request_implementation.rb"&gt;&lt;/script&gt;


&lt;p&gt;Now I wouldn't use this all the time, but for cases like sinatra's get requests,
it can really make for an awesome DSL. Before you implement it in your
own project, I would recommend reading over the docs for &lt;a href="http://www.ruby-doc.org/core-1.9.3/UnboundMethod.html"&gt;UnboundMethod&lt;/a&gt;
and read though the &lt;a href="https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb"&gt;sinatra source code&lt;/a&gt;
just so you know exactly what's going on. Since this article just skims
the surface of what is important to know when building a DSL, here are a few
resources that dig a little deeper:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://jroller.com/rolsen/entry/building_a_dsl_in_ruby"&gt;Building a DSL in Ruby Part I&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://jroller.com/rolsen/entry/building_a_dsl_in_ruby1"&gt;Building a DSL in Ruby Part II&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubybestpractices.com/"&gt;Chapters 2 and 3 of Ruby Best Practices&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://obiefernandez.com/presentations/obie_fernandez-agile_dsl_development_in_ruby.pdf"&gt;Agile DSL development in Ruby (Presentation Slides)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;What are some other resources and techniques you've used to make a great ruby DSL?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Using Rails localization outside of your views</title>
     <link href="http://highgroove.com/articles/2011/12/21/localizing_your_data.html" />
     <updated>2011-12-21T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/21/localizing_your_data.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://memegenerator.net/cache/instances/400x/11/11392/11665616.jpg" alt="If recycling is using something, why is cycling riding a bike?" style="float: right"&gt;&lt;/p&gt;

&lt;p&gt;When I went to Europe for the first time, first to England and then to France, I
was deeply obsessed with track cycling.  Since I was (kind of) writing my
Masters Thesis while my wife was (actually) doing serious research for hers, I
had plenty of spare time to hunt down every concrete or wood-banked oval in all
of France.  My process started out by simply looking for the famous ones like
Roubaix and Vélodrome d'Hiver.  I quickly realized that every town in France has
a great website and they nearly always listed the address of their velodrome if
they had one!  With that in hand, I would then search for it in Google Earth and
put a push-pin there.  This was a strange and silly obsession but it taught me
a few things.  It taught me to read a bit of French, to provide correct accents
to Google France's search site, and to do my best to search like I was actually
a French speaker.  I'm not sure if I succeeded, but this is the exact opposite of
what we want our users to have to do with any of the sites we create.  Luckily
Ruby on Rails provides extensive support for
&lt;a href="http://guides.rubyonrails.org/i18n.html"&gt;Internationalization&lt;/a&gt; (i18n for short)
via mechanisms such as Translation and Localization.  The prior simply creates
mappings between variables (and parameters) and some copy in the language to be
displayed.  The latter does things like format numbers, times and dates, and
currencies correctly according to the language to which we are
localizing.  This alone should make us ecstatic but we can leverage the
tools provided in even more exciting ways.&lt;/p&gt;

&lt;p&gt;More after the break.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Recently I have worked with a customer on accomplishing a very simple task:
Create a CSV template for download by their customers.  The content was mostly
static headers with a little bit of dynamic content to boot:&lt;/p&gt;

&lt;script src="https://gist.github.com/1501536.js?file=first_iteration.rb"&gt;&lt;/script&gt;


&lt;p&gt;Since we like to do a little something, show it to the customer, and see what
they think, this was a completely sane first step.  The static headers were
provided by them via a story in Pivotal Tracker, so we simply copied them into
the code and added a little business logic in the model.&lt;/p&gt;

&lt;p&gt;The client was happy and accepted the story but immediately created a second
story because they wanted a few more headers that weren't there.  Clearly, I can
fix this very easily: I just get the new headers, fire up the editor, add them,
and push:&lt;/p&gt;

&lt;script src="https://gist.github.com/1469495.js?file=more_headers.rb"&gt;&lt;/script&gt;


&lt;p&gt;Great.  Done.  Next project.&lt;/p&gt;

&lt;p&gt;Actually there are much cooler ways to do this, but first a short aside.  Early
on at Highgroove, during our weekly code-reviews, one of the team came across a
short and easy commit I had made.  The only change was to update some copy in
the view that was provided by the copy-writer at the client shop.  I had created
some generic text explaining what &lt;em&gt;I&lt;/em&gt; thought things did just as a place-holder,
knowing full well (and in fact creating a story asking for) new text which would
replace it later.  Actually this text was in the i18n file (&lt;code&gt;en.yml&lt;/code&gt;) file and looked
something like:&lt;/p&gt;

&lt;script src="https://gist.github.com/1469510.js?file=en.yml"&gt;&lt;/script&gt;


&lt;p&gt;And my commit actually updated &lt;code&gt;config/locales/en.yml&lt;/code&gt; rather than the view
itself.  My reviewer said "Have you let the client know they can simply edit the
translation file themselves when they want the text changed?"  To be honest, I
had no idea.  I got back a quick skitch that summed it up nicely:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20111212-x9x3iif75u7qqgns5yigd5b1tm.png" alt="Github's edit button!"&gt;&lt;/p&gt;

&lt;p&gt;Github provides so much great functionality it can be hard to describe it to
someone without running out of breath in the process.  One of those features is
the ability to edit some files in Github without checking out the repository.
This is great for people who aren't developers but are actively involved in the
development process in some way, like say, copy-writers!&lt;/p&gt;

&lt;p&gt;Great, so now we can work on models and edit files in the browser, thanks to the
folks at Github, but how does this work with CSVs?  Well, what if we can store the
headers themselves somewhere that the client can edit them without asking us?
Can we access the internationalization file from within Models and not just
views?  It turns out we can with the &lt;code&gt;#human_attribute_name&lt;/code&gt; method provided by
&lt;a href="http://apidock.com/rails/ActiveModel/Translation/human_attribute_name"&gt;ActiveModel::Translation&lt;/a&gt;.&lt;/p&gt;

&lt;script src="https://gist.github.com/1469559.js?file=better_model.rb"&gt;&lt;/script&gt;


&lt;p&gt;Note that to utilize the "human attributes" we define a new section of our
&lt;code&gt;en.yml&lt;/code&gt; file per the &lt;a href="http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models"&gt;Translations for Active Record Models&lt;/a&gt;
section of RailsGuides.&lt;/p&gt;

&lt;p&gt;This provides many advantages over the previous implementation:
* We separate model logic and data storage.  This is the same natural data
  abstraction that MVC is intended to provide.
* Multiple methods can now access the static headers and do whatever they may
  need to do with them (such as validate them later).  To do this in the model
  we would require a constant, a class variable, or some other mechanism to bind
  it to the model directly.&lt;/p&gt;

&lt;p&gt;Since the localization files are written in YAML we can leverage its flexibility
to &lt;a href="http://yaml.org/YAML_for_ruby.html#inline_collections"&gt;embed simple objects within&lt;/a&gt;
our files which leads to another application of i18n functionality in our code.
If a client has a complicated external collection of test-cases that is updated
often, perhaps based on their own agile or iterative process, then we can
leverage i18n in our testing regime.&lt;/p&gt;

&lt;p&gt;Consider a test-suite like the following:&lt;/p&gt;

&lt;script src="https://gist.github.com/1472796.js?file=another_model_spec.rb"&gt;&lt;/script&gt;


&lt;p&gt;In this case the list of the three expected countries (line 6) are provided by the
customer, as is the &lt;a href="https://gist.github.com/1472796#file_country"&gt;country file&lt;/a&gt;.
If they have a new and better test fixture that handles some complicated edge
case, then they have to provide us with the new file.  We can then analyze it, do the
right TDD thing by updating the test-suite, etc.  Or, the customer could update
&lt;code&gt;en.yml&lt;/code&gt; with the new test data and the necessary fixture, and we can keep the
test-suite exactly as it was.  It could potentially break at this point, which
is a great place to start our red-red-green TDD process:&lt;/p&gt;

&lt;script src="https://gist.github.com/1472820.js?file=another_model_spec.rb"&gt;&lt;/script&gt;


&lt;p&gt;Leveraging i18n within all aspects of a rails app, including testing and models,
rather than restricting ourself to our views empowers developers and clients in
our Agile process.  We can work on delivering high-quality code which is also
extremely flexible to the needs of the customer. This in turn allows the customer to make
necessary changes without a back-and-forth via a medium such as Tracker or a
chat-room.  Instead 'text-needed' or 'data-needed' stories can be created and
delivered without developers being involved unless they are necessary, making the
entire team more productive.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tracking Time the ROWE way</title>
     <link href="http://highgroove.com/articles/2011/12/15/tracking-time-the-rowe-way.html" />
     <updated>2011-12-15T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/15/tracking-time-the-rowe-way.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.gorowe.com/know-rowe/what-is-rowe/"&gt;ROWE&lt;/a&gt; means getting results done and not worrying about when it happens or how long it takes. This is a great way to get things done, but the amount of time spent on tasks can be an extremely useful metric.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20111215-kjbmkqjckg3aw41fr9jfbkaiut.jpg"&gt;&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;At Highgroove, we're strictly ROWE: it doesn't matter what hours we work or how much time we spend on things, as long as the work gets done and the customer is happy. Some people work the 9 to 5 while others work off and on 24 hours a day. Some people manage how they get things done with tools like paper or &lt;a href="http://culturedcode.com/things/"&gt;Things.app&lt;/a&gt;,  and everyone has a different workload and different set of customers they interact.  This is great because tons of work gets done and we don't have to continually interrupt ourselves to track how much time we are spending on projects.&lt;/p&gt;

&lt;p&gt;That said, tracking time comes in very handy for us in two ways. First up: new hires that are new to ROWE and not used to having the freedom and flexibility to work however they want don't always pick it up right away. Imagine that you're used to someone telling you what to do every minute of your day and suddenly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The office is regularly half-full due to people working crazy hours and/or working remotely (from home, other cities, and other states)&lt;/li&gt;
&lt;li&gt;All meetings are optional and people regularly skip things that feel they don't need to go to&lt;/li&gt;
&lt;li&gt;Someone leaves work early because they got a beta invite to &lt;u&gt;Star Wars: The Old Republic&lt;/u&gt; and want to start playing&lt;/li&gt;
&lt;li&gt;Beer is poured right after lunch on Friday&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Sounds like, uh, time to just go sit by the pool and read comic books!  That works for a day or few, but when your project falls on it's face and your customer is unhappy, you probably won't have a job for long.&lt;/p&gt;

&lt;p&gt;Until new developers at Highgroove feel comfortable that they have ROWE figured out, they are encouraged to track their time with &lt;a href="http://letsfreckle.com/"&gt;Freckle&lt;/a&gt; or &lt;a href="http://overcommitted.com/tictoc"&gt;TicToc&lt;/a&gt; or something similar. This isn't used for firing people or judging performance or billing, but  when combined with good metrics like customer satisfaction it's extremely useful: 20 hours a week and your 100% project's customer is happy means that you get more responsibilities if you want (and more pay).   60 hours a week and an unhappy customer means that something isn't working right, and that something (project management, responsibilities, development practices, customer communication and expectations, etc) needs to change.&lt;/p&gt;

&lt;p&gt;Once developers get a feel for how to get work done where only results matter, the time tracking can go away which tends to make people happier more and productive.&lt;/p&gt;

&lt;p&gt;However, the second useful case for time tracking is that developers track their time because they want to and they find it to be useful for gauging their efforts. For some, knowing that 40 hours of work done makes it easier to skip out early on Friday. For others, it's a handy way to divide up effort between multiple projects.&lt;/p&gt;

&lt;p&gt;A handful of us have started using &lt;a href="https://www.rescuetime.com/"&gt;RescueTime&lt;/a&gt; which sits in the background and figures out if your computer usage is productive or not.  This is a fantastic tool because it requires no effort or data entry and gives you similar metrics about time spent on projects. I was able to see that those two weeks that I spent playing what seemed like far too many hours of &lt;a href="http://kingdomrush.net/play-kingdom-rush.php"&gt;Kingdom Rush&lt;/a&gt; may have affected other things, but didn't prevent me from spending the usual amount of time on work and getting all of my work done.&lt;/p&gt;

&lt;p&gt;Do you track your time even if the numbers are only for you? Is the mere thought of time tracking enough to send you running in the opposite direction?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Refactoring Regular Expressions with Ruby 1.9 Named Captures</title>
     <link href="http://highgroove.com/articles/2011/12/14/refactoring-regular-expressions-with-ruby-1-9-named-captures.html" />
     <updated>2011-12-14T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/14/refactoring-regular-expressions-with-ruby-1-9-named-captures.html</id>
     <content type="html">&lt;div style="height:90px;"&gt;
  &lt;a href="http://www.flickr.com/photos/uncut/17446765/"&gt;&lt;img src="http://farm1.staticflickr.com/10/17446765_4b976c7d02_t.jpg" style="float:right;"/&gt;&lt;/a&gt;
  &lt;p&gt;
    I've often felt like Ruby Regexp captures are a bit clumsy.
  &lt;/p&gt;
  &lt;p&gt;
    Let's say we need to break apart phone numbers:
  &lt;/p&gt;
&lt;/div&gt;




&lt;script src="https://gist.github.com/1475412.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;After executing this match, we might do something like this with the parsed number:&lt;/p&gt;

&lt;script src="https://gist.github.com/1475483.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;What's up with the dollar signs and the sequential numbers?&lt;/p&gt;

&lt;p&gt;I feel like I'm writing assembly code and referring to registers or memory offsets or something.&lt;/p&gt;

&lt;p&gt;If I'm a new Ruby programmer reading this code, I might have no idea what is going on here.&lt;/p&gt;

&lt;p&gt;We can do better &lt;!-- -**-END-**- --&gt; if we upgrade from magical variables to the Regexp.last_match method:&lt;/p&gt;

&lt;script src="https://gist.github.com/1475488.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;At least this is a bit more readable than the magic variables.&lt;/p&gt;

&lt;p&gt;And it's probably easier for a newcomer to find documentation for &lt;a href="https://www.google.com/search?ix=sea&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=Regexp.last_match"&gt;Regexp.last_match&lt;/a&gt; than &lt;a href="https://www.google.com/search?ix=sea&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=$1"&gt;$1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But there's an even better way in Ruby 1.9 - &lt;a href="http://www.ruby-doc.org/core-1.9.3/Regexp.html#method-i-named_captures"&gt;named captures&lt;/a&gt;:&lt;/p&gt;

&lt;script src="https://gist.github.com/1475491.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;Now we've got readable code, and better documentation built into our regular expression.&lt;/p&gt;

&lt;p&gt;Are you using Ruby 1.9 yet? If so, have you had a chance to use named captures?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Lessons Learned at Global Day of Coderetreat</title>
     <link href="http://highgroove.com/articles/2011/12/13/lessons-learned-at-global-day-of-coderetreat.html" />
     <updated>2011-12-13T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/13/lessons-learned-at-global-day-of-coderetreat.html</id>
     <content type="html">&lt;div style="width:260px;float:right;"&gt;
  &lt;a title="adapted from Flacky Making his way through by khanb1, on Flickr" href="http://flickr.com/photos/albaraa/5953572377/"&gt;
    &lt;img src="https://img.skitch.com/20111213-dsseuedkmq36s1wmhf5iwsc25c.jpg" width="240", height="207" alt="adapted from Flacky Making his way through"/&gt;
  &lt;/a&gt;
  &lt;br /&gt;
  &lt;small style="font-size: 11px;padding: 0 0 0 13px;"&gt;
    &lt;a title="Flacky Making his way through" href="http://flickr.com/photos/albaraa/5953572377/"&gt;cc licensed ( BY )  flickr photo&lt;/a&gt;
    shared by &lt;a href="http://flickr.com/people/albaraa/"&gt;khanb1&lt;/a&gt;
  &lt;/small&gt;
&lt;/div&gt;


&lt;p&gt;In case you missed it, the awesome &lt;a href="http://blog.coderetreat.com/global-day-of-coderetreat"&gt;Globay Day of
Coderetreat&lt;/a&gt; occurred on
December 3rd.  The amount of fun I experienced was unexpected and impressive!
I learned some things too.  Read on to find out what.&lt;/p&gt;

&lt;p&gt;(Also, don't worry if you missed the code retreat, sad kitten has some good news
for you at the end of this post.)&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;I managed to make it out to Knoxville where &lt;a href="http://knoxvillesc.org/global-day-of-coderetreat"&gt;they held the most awesome code
retreat&lt;/a&gt;.  Congrats to
&lt;a href="http://twitter.com/#!/brianfriesen"&gt;Brian&lt;/a&gt;
&lt;a href="http://www.randomskunk.com/"&gt;Friesen&lt;/a&gt; for putting together such an excellent
event.&lt;/p&gt;

&lt;p&gt;For those not familiar with code retreats, you pair program with six different
people under different constraints during each session.  You delete all code
between sessions.  And you only work on one problem, &lt;a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life#Rules"&gt;Conway's Game of
Life&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lessons learned:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You can't code Game of Life in forty-five minutes.  Or &lt;em&gt;you&lt;/em&gt; can, if you're
really really good. Or if you've done it five times before in the same day
and you skimp on tests and still probably not even then.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sometimes you're the teacher, sometimes you're the student.  Enjoy both!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;C# is looking cooler and cooler.  But not cool enough to pull me away from
Ruby.  (Sorry .NET recruiters.  You can stop emailing me now.  Seriously.
Stop.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to make proper use of equality in ruby to generate a unique collection of
items.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Let's talk about number four!&lt;/p&gt;

&lt;p&gt;Most of the attendees were C# developers.  I was the lone ruby hold out and
convinced a couple of my fellow attendees to give ruby a try.  They were
enjoying the ruby exploration and implementation until we hit a little snag.&lt;/p&gt;

&lt;p&gt;I wanted to get a Set of a Point class instances.  Given an array of Points,
I wanted ruby to spit back out only the unique items.  Overriding == didn't
work.  Overriding .eql? didn't work either.  Neither did any combination
thereof.  Gah, this was extremely frustrating.&lt;/p&gt;

&lt;p&gt;After a precious wasted 10-15 minutes I, mildly embarassed, threw in the towel.
We moved on.. and of course, did not finish implementing GoL in ruby.&lt;/p&gt;

&lt;p&gt;The C# devs were still impressed with ruby but I couldn't let it go.  During the
lunch break, I spent some time (another 10-15 minutes) googling and came up
with:&lt;/p&gt;

&lt;script src="https://gist.github.com/1473766.js"&gt; &lt;/script&gt;


&lt;p&gt;See it in action &lt;a href="https://gist.github.com/1473203"&gt;here&lt;/a&gt;. I based the code on &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/230421"&gt;a
nice module implementation of
equality&lt;/a&gt;
&lt;a href="http://kentreis.wordpress.com/2007/02/08/identity-and-equality-in-ruby-and-smalltalk"&gt;and further discussion of equality in
ruby&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The key is to override both #hash and #eql?.&lt;/p&gt;

&lt;p&gt;Upon further reflection, my chagrin at ignorance of implementing equality in
arbitrary Ruby classes was misplaced.  The point of a code retreat is to
practice, to get better.  To learn from one another.  Sometimes, even when
you're the teacher, you're still the student. That's one of the reasons we &lt;a href="http://highgroove.com/articles/2010/03/20/the-4-things-we-look-for-in-a-code-review.html"&gt;love
code
reviews&lt;/a&gt;
&lt;a href="http://highgroove.com/articles/2011/02/06/cowboy-girl-programmers-dont-live-here.html"&gt;so much at
highgroove&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Have you gone to a code retreat?  If so, what did you learn?&lt;/p&gt;

&lt;p&gt;p.s. Oh, I almost forgot.  The great news for those of you who missed it, or
want to again, is that I'm hosting a &lt;a href="http://www.eventbrite.com/event/2604969534/auto"&gt;code retreat in Athens in
2012&lt;/a&gt;.  Come check
out it!&lt;/p&gt;

&lt;div style="float:right"&gt;
  &lt;a title="adapted from Cat smiling at sanctuary" href="http://flickr.com/photos/rikkis_refuge/183400812/"&gt;
    &lt;img src="https://img.skitch.com/20111213-qh1af8k7pdjnmq6yegp5qt8umi.jpg" /&gt;
  &lt;/a&gt;&lt;br /&gt;
  &lt;small&gt;
    &lt;a title="adapted from Cat smiling at sanctuary" href="http://flickr.com/photos/rikkis_refuge/183400812/"&gt;cc licensed ( BY)  flickr photo&lt;/a&gt;
    shared by &lt;a href="http://flickr.com/people/rikkis_refuge/"&gt;rikkis_refuge&lt;/a&gt;
  &lt;/small&gt;
&lt;/div&gt;

</content>
   </entry>
 
   <entry>
     <title>Breaking Bad Software Habits</title>
     <link href="http://highgroove.com/articles/2011/12/13/breaking-bad-software-habits.html" />
     <updated>2011-12-13T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/13/breaking-bad-software-habits.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/superfantastic/166215927/"&gt;&lt;img src="http://farm1.staticflickr.com/45/166215927_48b7336d26_m.jpg" style="float: right"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have only been a professional software developer for a few years, but
I feel like I have already acquired bad habits.&lt;/p&gt;

&lt;p&gt;One of the hardest for me to break is the desire to create software in a
cloistered environment where the requirements are stable and the best
technical approach always wins over other constraints like schedule and
cost.&lt;/p&gt;

&lt;p&gt;Thankfully Highgroove's iterative software development process forces me
to flee from these broken methods of building applications.&lt;/p&gt;

&lt;p&gt;Read on for more of my thoughts.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;I have a formal degree in computer science, and I am glad I have it.
However, all the assignments I completed in school had requirements that
were set in stone. These requirements would be published, often on
physical paper, and given out well in advance of the due date. This
works well when attempting to be fair to all students, but customers in
the real world rarely have requirements as stable as a classroom
assignment.&lt;/p&gt;

&lt;p&gt;The first company I worked for out of college claimed to do iterative
development, but the process really felt like
&lt;a href="http://en.wikipedia.org/wiki/Waterfall_model"&gt;waterfall&lt;/a&gt; with a few
small modifications. The solution to customers changing their
requirements was to try to nail down those requirements sooner. Code was
delivered in big releases every 6-9 months.&lt;/p&gt;

&lt;p&gt;These experiences started to shape my instincts: sometimes I feel that
uncertain or unclear requirements are a problem that must be solved
before development can start in earnest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That is so foolish.&lt;/strong&gt; I am learning that developing interesting
software often means it is impossible to know the "right answer" up front
... &lt;strong&gt;and that is OK.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer to uncertainty in software is not to view it as a problem,
&lt;strong&gt;but to embrace it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How am I learning to do that .. practically?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bias towards action:&lt;/strong&gt; if the "right answer" to a problem seems
unclear, bias towards implementing &lt;em&gt;some&lt;/em&gt; solution (even if you &lt;em&gt;know&lt;/em&gt;
it's not the best). Get it out there for the client (or even the
client's customers!) to use as soon as possible. The best solution will
come by iterating on the non-ideal solutions you unabashedly tried
at first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test-driven development:&lt;/strong&gt; Coming up with solutions quickly is good,
but not at the expense of bad code quality. The biggest wins of TDD are
not code correctness (though that's a nice byproduct), but the &lt;strong&gt;design
feedback&lt;/strong&gt; it gives. If the tests are hard to write, you are probably
writing smelly code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID design principles:&lt;/strong&gt; Learning about--and attempting to follow--
the principles of the &lt;a href="http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29"&gt;SOLID
mnemonic&lt;/a&gt;
have lead to improvements in the code I write. SOLID code is better able
to handle the changes that will inevitably come when doing iterative
development. For Rubyists specifically, I highly recommend &lt;a href="http://blog.rubybestpractices.com/posts/gregory/055-issue-23-solid-design.html"&gt;Gregory
Brown's
article&lt;/a&gt;
and &lt;a href="http://confreaks.net/videos/185-rubyconf2009-solid-ruby"&gt;Jim Weirich's
talk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In short, bad software development habits are easy to pick up,
especially in formal education and in companies that have not truly
adopted an agile/iterative approach. &lt;strong&gt;What bad habits have you
broken--or are still breaking--when developing software?&lt;/strong&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Fake It</title>
     <link href="http://highgroove.com/articles/2011/12/06/fake-it.html" />
     <updated>2011-12-06T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/06/fake-it.html</id>
     <content type="html">&lt;p&gt;&lt;img src="/images/blog/placekitten.jpg" alt="Place Kitten" style="float: right;"/&gt;&lt;/p&gt;

&lt;p&gt;One of the more complicated Ruby/Rails projects we work with at Highgroove
has many points where it interacts directly with the filesystem.&lt;/p&gt;

&lt;p&gt;Writing tests for an application whose code requires reading from or
writing to the filesystem presents challenges, especially if done
naively.&lt;/p&gt;

&lt;p&gt;While it's tempting to simply use the real filesystem during unit tests,
this presents a few problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tests may be brittle, breaking on systems that are not setup
just like the initial developer's local environment.&lt;/li&gt;
&lt;li&gt;Setting up fixtures on the real filesystem may not be plausible;
for instance, if the code interacts with system files (such as in
the example coming below!).&lt;/li&gt;
&lt;li&gt;Test code must be careful to clean up afterwards, even in error
cases. Otherwise, the file system could be left polluted, dirtying
the developer's machine and possibly breaking tests on the next run.&lt;/li&gt;
&lt;li&gt;Tests running in parallel may interact with one another, causing
random failures (e.g., on a continuous integration server or with
&lt;a href="https://github.com/grosser/parallel_tests"&gt;parallel_tests&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The filesystem is slow; when attempting to make unit tests as fast
as possible, the time to write, sync, and/or read from the
filesystem may become significant.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So what's the solution? &lt;strong&gt;Fake the filesystem during unit tests.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More after the break.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Consider the following (contrived) piece of code:&lt;/p&gt;

&lt;script src="https://gist.github.com/1439794.js"&gt; &lt;/script&gt;


&lt;p&gt;Now, what's the best way to test it? The tests can't touch &lt;em&gt;/etc/passwd&lt;/em&gt;
due to permissions, and even if they could, writing to &lt;em&gt;/etc/passwd&lt;/em&gt;
would be destructive to the system.&lt;/p&gt;

&lt;p&gt;How about mocking &lt;code&gt;File.read&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Assuming we're using &lt;a href="https://github.com/rspec/rspec-core"&gt;RSpec&lt;/a&gt; and &lt;a href="http://mocha.rubyforge.org/"&gt;mocha&lt;/a&gt;
for mocking:&lt;/p&gt;

&lt;script src="https://gist.github.com/1439838.js"&gt; &lt;/script&gt;


&lt;p&gt;This works, but tightly couples the test code. What if someone comes
along and refactors the production code, making use of &lt;code&gt;File.readlines&lt;/code&gt;
instead of &lt;code&gt;File.read.split&lt;/code&gt;?&lt;/p&gt;

&lt;script src="https://gist.github.com/1439856.js"&gt; &lt;/script&gt;


&lt;p&gt;The code still works, but the test breaks because &lt;code&gt;File.read&lt;/code&gt; is
stubbed, not &lt;code&gt;File.readlines&lt;/code&gt;. In fact, it's now reading from the real
system's /etc/passwd. The code still works, but the test broke. Ugh!&lt;/p&gt;

&lt;p&gt;A better solution is to stub the entire filesystem at a higher level,
giving a blank slate each time a new test runs. Nothing is ever
&lt;strong&gt;actually&lt;/strong&gt; written to the filesystem.&lt;/p&gt;

&lt;p&gt;Enter the &lt;strong&gt;&lt;a href="https://github.com/defunkt/fakefs"&gt;fakefs&lt;/a&gt;&lt;/strong&gt; gem.&lt;/p&gt;

&lt;p&gt;It's trivial to get up and running. If using bundler, I recommend adding
it to the &lt;code&gt;:test&lt;/code&gt; group:&lt;/p&gt;

&lt;script src="https://gist.github.com/1439875.js"&gt; &lt;/script&gt;


&lt;p&gt;Next, configure RSpec to include the fakefs helpers to automatically
activate and deactivate fakefs whenever a test is tagged with &lt;code&gt;fakefs:
true&lt;/code&gt;:&lt;/p&gt;

&lt;script src="https://gist.github.com/1439883.js"&gt; &lt;/script&gt;


&lt;p&gt;And finally, write tests that are tagged with &lt;code&gt;fakefs: true&lt;/code&gt;. But
this time, test code can manipulate any part of the filesystem, knowing
it's completely emphemeral and isolated:&lt;/p&gt;

&lt;script src="https://gist.github.com/1439921.js"&gt; &lt;/script&gt;


&lt;p&gt;Voila! While there is a bit more test code, the test is verifying
behavior, not the specific implementation. &lt;strong&gt;Do you have any other tips
for testing code that interacts with the filesystem?&lt;/strong&gt;&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Scratching Your Own Itch in the Badgerworks</title>
     <link href="http://highgroove.com/articles/2011/12/05/scratching-your-own-itch.html" />
     <updated>2011-12-05T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/12/05/scratching-your-own-itch.html</id>
     <content type="html">&lt;p&gt;"With all of the people doing this, why hasn't anyone ever just made a ..."&lt;/p&gt;

&lt;p&gt;"I really like doing this, but everytime I get to this point I struggle.  I need
to make that better."&lt;/p&gt;

&lt;p&gt;"Man... what I really need is something that makes this job less tedious!"&lt;/p&gt;

&lt;p&gt;&lt;img src="http://memegenerator.net/cache/instances/400x/9/9721/9954348.jpg" alt="Philosoraptor scratces his itch" align="right" /&gt;&lt;/p&gt;

&lt;p&gt;Those sentiments have reared their ugly heads in some way or another with every
crafty endeavour in which we at Highgroove have gotten involved.  Sometimes those
crafts are working on bikes (crafty and artisanal as well as mechanical),
brewing beer (crafty, artisinal, and after some patience, tasty if you're
careful), working on rails apps (crafty and often fun!), or pulling shots of
espresso (crafty, tasty, and caffeinated.  Sometimes with latte art.)  Instead
of simply wishing there was a solution, Highgroove encourages us to solve the
problem, not just for ourselves, but for others.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Highgroove's team is expected to be made up of craftsmen and -women in our work
not only by &lt;em&gt;asking&lt;/em&gt; us to be such, but also providing us with time to work on
our own projects, contribute to open-source projects, and build internal tools
to help the team work better.  As a result of this expectation, the
&lt;a href="http://highgroove.com/badger_works.html"&gt;Highgroove Badgerworks&lt;/a&gt; has not one
but many exciting projects we not only developed to use internally but also
release for your use and enjoyment!  In the cases of our open-source projects
and internal tools, we start to eat our own dogfood as quickly as possible,
often before the developer is "ready" to do so (as was the case with
&lt;a href="http://www.reflecticle.com/"&gt;Reflecticle&lt;/a&gt; when we started using it to track our
work internally).  This bleeding-edge mentality has advantages.  It reminds us
that often 85% correct is "correct enough to ship" because things will
undoubtably change (and an over-sharpened sword is often brittle).  It also
encourages flexibility in our code; the more flexible our code is, the easier it
is to respond to the wants and needs and likes and dislikes of early adopters.&lt;/p&gt;

&lt;p&gt;Continuing education of our team is also incredibly important, and building
our own projects allows us to do that by "finally" getting to play with cool
technologies we've come across during research for our work but have never had
a chance to use.  Want to write a mobile app using Sencha touch?  No
problem.  Want to finally build a Rails 3.1 app, or a Sinatra app, or somehow
integrate Hadoop into something you do?  Go for it.  Tired of not knowing
enough about Sunspot and Solr even though there is expertise in house?  Please
do something cool with it, and then, please ask questions or submit patches.&lt;/p&gt;

&lt;p&gt;After you've honed your craft, built your toy, or added functionality to an
existing project with a patch, it's time to give back to the rest of the team by
showing them what you've done.  If the project or tool is just plain neat and
you want to show it off we encourage you to step up and do a tech-talk for the
team and any visitors we may have.  These tech-talks are an informal break from
the rest of our work during which we can all take some time to learn something
new together in 15-45 minutes.  This is a great forum to get feedback on your
work to date, ask for help on those niggling details that are still to be worked
out, and get everyone else excited about your pet-project as well as using your
new tool in their own project.&lt;/p&gt;

&lt;p&gt;If, in addition to being interesting and fun, your tool can contribute to
Highgroove's day-to-day workflow, as our soon to be released ROWEapp and
Reflecticle do, we encourage the team to start using them, and even developing
them.  The ROWEapp is a great internal project for tracking your progress each
iteration of a project.  It ties in with the other tools we use (PivotalTracker,
LetsFreckle, etc.) and allows us to see the progress the entire team is making
on each of the various on-going projects Highgroove is involved in.  It has also
provided a fantastic place for the team to work together on a cutting-edge rails
app where breaking things or making mistakes is not the end of the world.  In
the past month so much progress has been made by one of our developers that it
has gone from being a great 'scratch your own itch' application to a product
nearly ready to ship to some of our other friendly ROWEs including
&lt;a href="http://www.rippleit.com/"&gt;ripple&lt;/a&gt;, &lt;a href="http://matchstic.com/"&gt;Matchstic&lt;/a&gt;,
and &lt;a href="http://dealerignition.com/"&gt;Dealer Ignition&lt;/a&gt;.  For us this is extremely
exciting!&lt;/p&gt;

&lt;p&gt;If you have the itch, it's pretty likely others do, too.  If you've done
your search of all the likely sites to find your solution and have come up
empty, it may be time to scratch your own itch.  It's likely you are solving a
problem many people have.  Once you've done so, Congratulations on contributing
to the diverse and useful software ecosystem!&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Don't Settle on Just One Test Framework!</title>
     <link href="http://highgroove.com/articles/2011/11/29/testing-and-good-design.html" />
     <updated>2011-11-29T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/29/testing-and-good-design.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://www.bootspring.com/wp-content/uploads/2010/08/testing-darth-vader-300x240.jpg" alt="I find your lack of tests disturbing..." align="right" /&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove Studios, we're hyperspecialists in Ruby on Rails web application development.  Not only do we write amazingly complicated code on time and on budget, but we follow up all our work with tests so we &lt;em&gt;know&lt;/em&gt; our code works.&lt;/p&gt;

&lt;p&gt;This is not without its problems however, as a test suite can become just as bloated and difficult to update as the code base it tests!  This week, I'll talk about some of the ways I've learned to approach writing tests.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Since I began working for Highgroove Studios back in April, I have been innundated with the importance of thorough and reliable testing.  Given the culture of performance and quality at Highgroove Studios, I knew that I had to find a way through the maze of test frameworks and options.&lt;/p&gt;

&lt;p&gt;After struggling with some very large, brittle test suites, it dawned on me that good test design, just like designing the application itself, was the key to success.  Maybe challenging some of my own assumptions about testing was in order as well!&lt;/p&gt;

&lt;p&gt;Once I realized that I needed to focus on writing better tests, instead of writing them faster and getting them to pass, I turned to Google and found some really good stuff that I wanted to share:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off"&gt;Cucumber Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cucumber/cucumber-rails/issues/174"&gt;Cucumber Issue Tracker on Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://concordion.org/Technique.html"&gt;Cucumber Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.agiledata.org/essays/tdd.html"&gt;Essay on TDD and Agile methodology&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.carbonfive.com/2010/10/21/rspec-best-practices/"&gt;Rspec Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;What all of this information made me realize was that I was trying to accomplish all of this with just a single test framework and certain ones align to Test Driven Development (TDD) and Acceptance Testing (BDD - Behavior Driven Development) better than others do.  (Figure 2 in the AgileData link explains visually why I was wrong!)&lt;/p&gt;

&lt;p&gt;After spending the time pondering my own practices, I decided to split apart the two tasks (BDD, and TDD) into Cucumber and Rspec tests, respectively.  After making the switch from an all-or-nothing, single test suite mentality to a "use what works best" mentality I've seen both the quality and ease of coding of my test increase.  Its amazing what happens when you stop trying to cram a square peg through a triangle hole!&lt;/p&gt;

&lt;p&gt;I prefer both Rspec and Cucumber for TDD and BDD, but you might have a different method.  If so, what is it and how does it make your day-to-day test writing simpler and more efficient?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Demo on Getting Things Done with Things.app</title>
     <link href="http://highgroove.com/articles/2011/11/28/tech-demo-on-getting-things-done-with-things.app.html" />
     <updated>2011-11-28T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/28/tech-demo-on-getting-things-done-with-things.app.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6420107303/" title="Tech Demo on productivity hacking. Getting moar things done by @ckdake by highgroove, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7012/6420107303_603f788214_m.jpg" width="240" height="180" alt="Tech Demo on productivity hacking. Getting moar things done by @ckdake" align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week's Tech Demo was on Monday because of the holidays. This is a recurring Tech Demo we've done before, and one of my favorites.&lt;/p&gt;

&lt;p&gt;We're all productivity junkies at Highgroove, and this week's talk was chock full of useful advice, tips, and tricks from our Methodologist, &lt;a href="http://highgroove.com/about/chris.html"&gt;Chris&lt;/a&gt;.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;One of the key points in Chris' talk is whatever system you're using, be it &lt;a href="http://culturedcode.com/things/"&gt;Things.app&lt;/a&gt;, &lt;a href="http://www.pivotaltracker.com"&gt;Pivotal Tracker&lt;/a&gt;, or just pen and paper -- there are 5 key habits that highly effective folks use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capture Everything in a trusted system&lt;/li&gt;
&lt;li&gt;Keep your Inbox Zero&lt;/li&gt;
&lt;li&gt;Start Your Day Right&lt;/li&gt;
&lt;li&gt;Review Everything Weekly&lt;/li&gt;
&lt;li&gt;Do Due Dates Right&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This Tech Demo wasn't as technical as usual, but ended with some real live question and answers, and a demo of how to use some of these habits in practice.&lt;/p&gt;

&lt;p&gt;For Highgroovers, the demo is on the Time Flux Capacitor (our Drobo-powered network share) for download.  In other news, we're thinking of opening up our Tech Demos, like other tech companies do.  If we did, would you (our readers) attend or watch in a live-streaming fashion?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Classifying Data with Discriminant Analysis</title>
     <link href="http://highgroove.com/articles/2011/11/22/classifying-data-with-discriminant-analysis.html" />
     <updated>2011-11-22T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/22/classifying-data-with-discriminant-analysis.html</id>
     <content type="html">&lt;p&gt;&lt;img width="240" height="180"  src="http://i.imgur.com/6tl2n.png" alt="Classify ALL the data!" style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Cluster_analysis"&gt;Cluster analysis&lt;/a&gt; methods have been gaining popularity as a way of Relating pieces of data in large datasets with one another. Examples in social networking are obvious: friends on Facebook cluster into cliques and communities, which cluster into even larger groups. Demographics and other marketing research can also be aided by sorting prospective customers into groups based on preference.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;When the clusters are known, and ample training data is available, &lt;a href="http://en.wikipedia.org/wiki/Linear_discriminant_analysis"&gt;discriminant analysis&lt;/a&gt; is particularly effective at classifying new data. Discriminant analysis methods are built into the R programming language (something we've &lt;a href="http://highgroove.com/articles/2011/10/21/tech-demo-on-the-r-project-for-statistical-computing.html"&gt;discussed&lt;/a&gt; a bit in the past) with a standard package. However, R can be cumbersome to use by itself (and the syntax still seems a bit bizarre to me personally), so I used &lt;a href="https://sites.google.com/a/ddahl.org/rinruby-users/"&gt;Rinruby&lt;/a&gt;, a gem which gives direct access to R methods and data, to put a nice Ruby wrapper around it. Below is some example code that analyzes a well-known clustering test dataset, the &lt;a href="http://en.wikipedia.org/wiki/Iris_flower_data_set"&gt;Fisher iris data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Say our iris data is contained as an array ("training_rows") of hashes that each look like&lt;/p&gt;

&lt;script src="https://gist.github.com/1387743.js"&gt; &lt;/script&gt;


&lt;p&gt;(where the species is given as 1, 2, or 3). We can load our data into a DiscriminantAnalysis instance and start predicting in just a few lines:&lt;/p&gt;

&lt;script src="https://gist.github.com/1387740.js"&gt; &lt;/script&gt;


&lt;p&gt;Every prediction comes as a hash with a confidence score to check the quality of the classification. This code uses a &lt;em&gt;linear&lt;/em&gt; analysis (i.e., it separates classes by lines or planes); the pretty scatterplot up top was generated using the iris data with &lt;a href="http://en.wikipedia.org/wiki/Quadratic_classifier"&gt;&lt;em&gt;quadratic&lt;/em&gt;&lt;/a&gt; analysis, which can be achieved in the code above by simply replacing "init_lda_analysis" with "init_qda_analysis".&lt;/p&gt;

&lt;p&gt;R allows for tons of manipulation of the analysis once it's loaded, some of which has been built in to the DiscriminantAnalysis class (scatterplots, accuracy and significance testing, etc.).&lt;/p&gt;

&lt;p&gt;Since we're all about contributing to the open source community at Highgroove, I've packaged these methods into a gem called &lt;a href="https://github.com/brianstanwyck/harlequin"&gt;harlequin&lt;/a&gt; (cheesily enough after one of the irises in Fisher's data). If you have a working copy of R on your machine, you can get the code above running by just adding the proper &lt;code&gt;require&lt;/code&gt;s for the gem. Feel free to check it out and help to make it more awesome!&lt;/p&gt;

&lt;p&gt;Have you used clustering methods before? How do you deal with heavy-duty data processing in Ruby?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>(New) Team Work</title>
     <link href="http://highgroove.com/articles/2011/11/22/%28new%29-team-work.html" />
     <updated>2011-11-22T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/22/%28new%29-team-work.html</id>
     <content type="html">&lt;p&gt;&lt;img width="240" height="180"  src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Victory_huddle.jpg/766px-Victory_huddle.jpg" alt="Team Huddle" style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;The first couple of weeks in a new position for a new company is usually peppered with stressful stretches of striving to become useful and relevant mixed with hours of boredom working on a project of little importance.  At Highgroove, we are immediately thrown into the mix and are expected to perform.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Jason F. and I shared a start date.  We reveled in our goodie bags filled with organic candy and stickers, fiddled with the settings on our new Macbook Pros, and giggled (at least I did) over how much caffeine I was consuming from our office's Espresso machine.&lt;/p&gt;

&lt;p&gt;Then we got to work.  I met with my client, talked about what he expected for our first iteration, then was released to make it happen.  Harsh reality has never been so pleasant.  Where in many environments, asking questions feels discouraged to avoid cause for doubt of your abilities, at Highgroove, not asking soon enough is more discouraged.  The team at Highgroove is more than eager to not only answer quick questions, but savor the more difficult ones.  Even as a new member, my time is valued by the whole team; they want me to succeed with them.  And because of that, I will.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Demo on Merging Conflicting Code</title>
     <link href="http://highgroove.com/articles/2011/11/18/tech-demo-on-merging-conflicting-code.html" />
     <updated>2011-11-18T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/18/tech-demo-on-merging-conflicting-code.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6359208617/" title="Tech Demo on Merging Codebases by highgroove, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6225/6359208617_e492cb55b4_m.jpg" width="240" height="180" alt="Tech Demo on Merging Codebases" align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dave Worth's Tech Demo today is on merging codebases, using some workflow tricks and the &lt;a href="https://github.com/tpope/vim-fugitive"&gt;GitFugitive&lt;/a&gt; vim plugin ("a Git wrapper so awesome, it should be illegal") by &lt;a href="http://tpo.pe/"&gt;Tim Pope&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We regularly work with other software development teams, and merging codebases and features is routine work for us. Dave shows us his workflow so we can get faster, and more efficient at merging lots of features all at once, together.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;We love sharpening our axes at Highgroove.  One way is through slick tools that can save us typing, time, and just make things easier.  Using git through an interactive rebase with conflicts can be daunting.  Dave shows us how to use vim, coupled with git, along with Git Fugitive to make quick work of a nasty rebase.&lt;/p&gt;

&lt;p&gt;For more info on some of the tools, here are some links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git Fugitive plugin - &lt;a href="https://github.com/tpope/vim-fugitive"&gt;https://github.com/tpope/vim-fugitive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Vimcasts - &lt;a href="http://vimcasts.org/"&gt;http://vimcasts.org/&lt;/a&gt; (lots of good stuff including basically Dave's demo over n parts)&lt;/li&gt;
&lt;li&gt;MacVim - &lt;a href="http://code.google.com/p/macvim/"&gt;http://code.google.com/p/macvim/&lt;/a&gt; - (like Textmate only different) Zing!&lt;/li&gt;
&lt;/ul&gt;

</content>
   </entry>
 
   <entry>
     <title>Debugging Best Practices</title>
     <link href="http://highgroove.com/articles/2011/11/16/debugging-best-practices.html" />
     <updated>2011-11-16T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/16/debugging-best-practices.html</id>
     <content type="html">&lt;p&gt;At rubyhoedown, the inimitable &lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt; gave an
awesome presentation on using the debugger in ruby.  Before his new found
respect for the ruby debugger, Jim told us that puts statements worked just fine
for him.&lt;/p&gt;

&lt;p&gt;And this is true.  You can get by with puts.  But, you can get by much faster
using the debugger.  Read on to find out when to use the debugger and how.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Firstly, when should you use the the ruby debugger? Simple.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20111116-qw69611gfrjg7ghhc49wgqj26y.png" alt="f6595e4e-4c46-4331-9e9d-2f3d8b0556dd" alt="use debugger all the times" /&gt;&lt;/p&gt;

&lt;p&gt;Actually, there is one case in which puts is better than the debugger but let's
touch on that later.  For now, let us look at how to use the debugger.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Require ruby-debug in your source code.  Use ruby-debug19 for ruby 1.9+.  If
in rails, add ruby-debug / ruby-debug19 to your Gemfile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wherever you would put a puts statement, replace with 'debugger; true'.&lt;sup&gt;[0]&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Once you're in the debugger, you can revert to your puts using ways.  puts any
expression to evaluate it. Protip: or type in 'set autoeval' so you don't have to use
puts!!  You can even set this in an .rdebugrc file.  &lt;a href="https://gist.github.com/1369987"&gt;Example&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;The sweet spot of debugger commands.&lt;/h1&gt;


&lt;ol&gt;
&lt;li&gt;n - step over the next line (don't step into a function)&lt;/li&gt;
&lt;li&gt;s - step into the next line (into a function or block)&lt;/li&gt;
&lt;li&gt;c - continue until another breakpoint or execution completes&lt;/li&gt;
&lt;li&gt;v l - view all locally scoped variables&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;For a more comprehensive overview of commands, check out &lt;a href="http://cheat.errtheblog.com/s/rdebug/"&gt;errtheblog's
cheatsheet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, as I mentioned before, there is one time where I like puts over the ruby
debugger.  When you want to view the change of data throughout the execution of
a program, puts to a log file will give you a higher level overview.&lt;/p&gt;

&lt;p&gt;Can you think of any others?  How do you use the debugger?&lt;/p&gt;

&lt;div style='font-size: 85%'&gt;
&lt;p&gt;[0] 'debugger' does not act like a traditional breakpoint.  Instead of halting
execution before the 'debugger' line, the ruby-debugger halts execution
after.  Therefore, we drop a '; true' to ensure that we don't step out of
a function or into a method.&lt;/p&gt;
&lt;/div&gt;

</content>
   </entry>
 
   <entry>
     <title>The Great Campfire Experiment</title>
     <link href="http://highgroove.com/articles/2011/11/15/the-great-campfire-experiment.html" />
     <updated>2011-11-15T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/15/the-great-campfire-experiment.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://campfirenow.com/images/logo_campfire-full.png" alt="Campfire" style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;At Highgroove, we like using the right tool for the job, but we also don't like getting too bogged down in thinking about what we should use. We recently switched our internal company chat from &lt;a href="https://www.google.com/search?aq=f&amp;amp;ix=acb&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=sky"&gt;Skype&lt;/a&gt; to &lt;a href="http://campfirenow.com"&gt;Campfire&lt;/a&gt;, but it wasn't a just simple switch to flip.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;We like to use Skype to talk to our customers, since it allows us to be in constant contact with our customers, and it makes it easy to have face to face conversations with them when we can. Since we were already using Skype to talk to customers, we also made a group chat for Highgroovers to talk to one another.&lt;/p&gt;

&lt;p&gt;It wasn't a perfect solution, but it was an easy one. As we've been growing, the issues have started to bother us more and more, but it's conveience was impossible to beat. So how do we switch? It's hard to give up something that's already so integrated in our day to day lives. We weren't even sure if the benefits of switching outweighed the convienence of the current solution.&lt;/p&gt;

&lt;p&gt;We decided the best way was to run an experiment. We had heard great things about &lt;a href="http://campfirenow.com"&gt;Campfire&lt;/a&gt;, and it seemed nice, but would it fit our needs? Our null hypothesis was that Campfire was just as good as Skype, and our alternative hypothesis was that Campfire was better and would fit our needs better. To test this, we decided to use Campfire for 1 week and then evaluate it afterwards.&lt;/p&gt;

&lt;p&gt;Starting on a Monday, we all opened up Campfire as well and didn't talk at all in our old Skype group chat. We quickly found things we enjoyed, like inline images, flexible notifications via Propane, and Pivotal Tracker integration, along with things we missed, such as direct messages. Anytime we ran into something we liked or hated, we were vocal.&lt;/p&gt;

&lt;p&gt;I collected these opinions, and at the end of the week, asked how they had changed or if they were still issues. As a team we saw that the benefits outweighed the drawbacks and switched. While we would have eventually switched to something better if we sat around longer, we're already enjoying Campfire, and working to improve our experience (like setting up &lt;a href="http://hubot.github.com/"&gt;Hubot&lt;/a&gt;) with it now, something that would have had to wait for us to decide on the best chat system if we didn't just bias towards action.&lt;/p&gt;

&lt;p&gt;How does your organization make decisions? Do you try to decide on the best solution and then use it, or do you try to throw spaghetti against the wall and see what sticks?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>One Week In</title>
     <link href="http://highgroove.com/articles/2011/11/15/one-week-in.html" />
     <updated>2011-11-15T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/15/one-week-in.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://farm1.static.flickr.com/35/102448403_faffe9bac7.jpg" alt="Help" width=177 style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;After a week of working at Highgroove I am impressed at our efforts to provide everything a developer needs to start creating the best software possible through the right hardware, tools, and support.  For someone like myself, who had lots of programming experience but knew little about Ruby on Rails, this was invaluable in getting me into the Rails trenches and helping my client.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Although I received lots of cool things on my first day of work nothing stood out like the shiny, new, top of the line Macbook Pro sitting on the table.  It put the other work laptops I have received, a Windows XP Dell and a worn out Apple Powerbook, to shame.  Our policy on tools also separates Highgroove from the rest of the pack.  In other places I would have to do a sales pitch to negotiate my way into the sea of paperwork in order to get permission to use a non-standard tool that might help me get my work done.  At Highgroove it is not only encouraged but required that I get whatever I need to do my best.  If there is a tool unknown to the team that I think will help, I am required to show it off in case it might help them in their work.&lt;/p&gt;

&lt;p&gt;The most powerful tool in getting a new developer up to speed costs nothing but time.  I've never had an employer that used pair programming, but we encourage and require it.  Having someone with more Rails knowledge available to bounce ideas and problems off of gives more insight into the development process than any book or tutorial ever could.  Several of the software bugs that caused me to spend too much time banging my head into my desk were quickly resolved through pair programming.  No two developers think alike, and having a second thought process in the mix helps avoid lost time and benefits both partners in seeing how the other operates.  Now I wouldn't work anywhere that didn't encourage it.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Combining Many Customer Databases into One</title>
     <link href="http://highgroove.com/articles/2011/11/08/combining-many-customer-databases-into-one.html" />
     <updated>2011-11-08T00:00:00-05:00</updated>
     <id>http://highgroove.com/articles/2011/11/08/combining-many-customer-databases-into-one.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2444/3549285383_11de3317a6_m.jpg" alt="Keys" style="float: right;" &gt;&lt;/p&gt;

&lt;p&gt;Here at Highgroove we like a good challenge, and we love it when we can meet a challenge with a simple and elegant solution.&lt;/p&gt;

&lt;p&gt;Recently we had a customer with a great problem to have - they had signed up lots of new customers and were experiencing some growing pains.&lt;/p&gt;

&lt;p&gt;A typical Ruby on Rails app has one database. This app had one database &lt;em&gt;per customer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Routine tasks like launching servers, deploying code, or migrating databases were taking much longer than normal because they had to be performed per customer instead of just once.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;What this app needed instead was &lt;a href="http://en.wikipedia.org/wiki/Multitenancy"&gt;Multitenancy&lt;/a&gt; - a fancy word for combining the customers into one database.&lt;/p&gt;

&lt;p&gt;To combine safely, we'd need to ensure each customer's &lt;a href="http://en.wikipedia.org/wiki/Unique_key"&gt;unique keys&lt;/a&gt; no longer were in conflict with each other.&lt;/p&gt;

&lt;p&gt;Here is an example of unique keys before the merge:&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th colspan="2"&gt;Customer A&lt;/th&gt;
    &lt;th colspan="2"&gt;Customer B&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;Bob&lt;/td&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;Frank&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;Alice&lt;/td&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;Eleanor&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;And after the merge:&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;th colspan="2"&gt;Customer A &amp;amp; B&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;Bob&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;Frank&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;Alice&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;Eleanor&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;You can see the unique keys are no longer unique.&lt;/p&gt;

&lt;p&gt;How do we fix this? Time to look at some code:&lt;/p&gt;

&lt;script src="https://gist.github.com/1351305.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;This bit of code will give us the maximum id across all tables in all customer databases.&lt;/p&gt;

&lt;p&gt;Once we know the maximum id, we can reassign each customer's unique keys with enough offset to ensure there are no conflicts:&lt;/p&gt;

&lt;script src="https://gist.github.com/1351355.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;This will give us the combined table:&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;td colspan="3"&gt;Customer A &amp;amp; B&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;Bob&lt;/td&gt;
    &lt;td&gt;customer_a&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;Alice&lt;/td&gt;
    &lt;td&gt;customer_a&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;5&lt;/td&gt;
    &lt;td&gt;Frank&lt;/td&gt;
    &lt;td&gt;customer_b&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;6&lt;/td&gt;
    &lt;td&gt;Eleanor&lt;/td&gt;
    &lt;td&gt;customer_b&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;Now we're off to the races - with a single database containing records for all of our customers - and no unique key conflicts!&lt;/p&gt;

&lt;p&gt;Have you ever had to combine conflicting database records? How did you tackle the problem?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Using Active Shipping for Shipping Rate Estimates</title>
     <link href="http://highgroove.com/articles/2011/11/01/using-active-shipping-for-shipping-rate-estimates.html" />
     <updated>2011-11-01T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/11/01/using-active-shipping-for-shipping-rate-estimates.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20111101-q872dck1uxyar1w8w378sprip2.preview.png" alt="Ship it!" style="float:right"&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Shopify/active_shipping/"&gt;Active Shipping&lt;/a&gt; is a nifty Shipping API extension for Active Merchant. It provides methods for interacting with common shipping carrier APIs. Recently we used Active Shipping on a client's e-commerce site to provide customers with many shipping options from several carriers.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;h2&gt;Getting Rates&lt;/h2&gt;

&lt;p&gt;To get shipping rates for a carrier, you first need to "package" up some information about what you are shipping. Using the &lt;a href="https://github.com/Shopify/active_shipping/blob/master/lib/active_shipping/shipping/package.rb"&gt;Package&lt;/a&gt; class you can build an array of packages. Use each package's dimensions, weight, and the unit system you are measuring with (this will default to metric) to create a new package. Here in an example package:&lt;/p&gt;

&lt;script src="https://gist.github.com/1331564.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;From working with Active Shipping and various carrier APIs we have learned that all carriers require a package weight. Some will return results for a package with no dimensions. However, rates will vary greatly depending on the dimensions of your packages, so it is a good idea to always include them so that your rate estimates are accurate.&lt;/p&gt;

&lt;p&gt;Along with the array of packages, Active Shipping needs to know some information about the origin and destination of your shipment. Using the &lt;a href="https://github.com/Shopify/active_shipping/blob/master/lib/active_shipping/shipping/location.rb"&gt;Location&lt;/a&gt; class you can create an origin and destination location for your shipment. Here is an example of a destination (the origin is built the same way):&lt;/p&gt;

&lt;script src="https://gist.github.com/1331567.js?file=gistfile1.rb"&gt;&lt;/script&gt;


&lt;p&gt;The Location class takes country, state, city, and zip. Working with Active Shipping and various carrier APIs we have found you can get away with just using country and zip code if needed.&lt;/p&gt;

&lt;p&gt;Once we have an origin, destination, and packages we are ready to make request to the carriers' APIs. Initialize the carrier you want to you use, then call its &lt;code&gt;find_rates&lt;/code&gt; method:&lt;/p&gt;

&lt;script src="https://gist.github.com/1331569.js?file=gistfile1.txt"&gt;&lt;/script&gt;


&lt;h2&gt;Getting access to carrier APIs.&lt;/h2&gt;

&lt;p&gt;Each carrier requires its own set of credentials. You can sign up for each carrier's service on their respective websites. While the UPS codes seem to always "just work", you will need to pass &lt;code&gt;:test =&amp;gt; true&lt;/code&gt; as a param to get Fedex to work while you are testing your application. We were unable to get the USPS API to provide rates in test mode). To get the USPS API to provide rates you will need to contact and have your production API access turned on. The best way to do this is the call the number provided in the confirmation email they sent. Requests made via email seem to take a couple days to get processed.&lt;/p&gt;

&lt;p&gt;Active Shipping is just one of the great extensions of Active Merchant. What other Active Merchant extensions are you using in your e-commerce sites/development?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Demo on Sencha Touch Mobile HTML 5 Framework</title>
     <link href="http://highgroove.com/articles/2011/10/28/tech-demo-on-sencha-touch-mobile-html-5-framework.html" />
     <updated>2011-10-28T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/28/tech-demo-on-sencha-touch-mobile-html-5-framework.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/highgroove/6289071529/" title="Tech Demo on Sencha Touch. Mobile HTML 5 framework. by highgroove, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6217/6289071529_e23d553610_m.jpg" width="240" height="180" alt="Tech Demo on Sencha Touch. Mobile HTML 5 framework." align="right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week's Tech Demo was on &lt;a href="http://www.sencha.com/products/touch/"&gt;Sencha Touch&lt;/a&gt;, a cross-platform framework aimed at next generation, touch enabled devices.&lt;/p&gt;

&lt;p&gt;Brandon went over a small sample Sencha Touch and Ruby on Rails app that we're using as a "spike" on the Beltline for Bikes Project for the &lt;a href="http://matchstic.com"&gt;Matchstic&lt;/a&gt; "On the House" community service project.&lt;/p&gt;

&lt;blockquote&gt;It's currently compatible with Apple iOS 3+, Android 2.1+, and BlackBerry 6+ devices. Sencha Touch is the world's first app framework built specifically to leverage HTML5, CSS3, and Javascript for the highest level of power, flexibility, and optimization. We make specific use of HTML5 to deliver components like audio and video, as well as a localStorage proxy for saving data offline.&lt;/blockquote&gt;




&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Basically, it plugs right into a Ruby on Rails application, and even has a similar MVC style structure. Sencha can help build out mobile applications that can be submitted into the app store (or just bookmarked on the device).  Because they use HTML5 and are backed by a web application, there's a great use-case for data-driven sites that don't require native graphics or access to hardware.&lt;/p&gt;

&lt;p&gt;Another neat tool for our tool belt.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Starting Off Right</title>
     <link href="http://highgroove.com/articles/2011/10/27/starting-off-right.html" />
     <updated>2011-10-27T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/27/starting-off-right.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://farm6.static.flickr.com/5006/5296034697_1f44cb771f_m.jpg" alt="Gifts" style="float: right;" &gt;&lt;/p&gt;

&lt;p&gt;I'll be honest. My reaction to my first morning in the Highgroove office was
one which I thought I would not be sharing. After talking to a couple other
Highgroovers, however, I realized it was a pretty common reaction. To us, our
first day felt a little bit like Christmas morning.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;I fully realize how cheesy this sounds, but showing up to a new desk covered
in a goodie bag and developer treats must have brought out the giddy 10 year
olds in us. My previous jobs have usually provided me with some inherited
file folders, a pile of training and maybe a dying fern on the first day.
With Highgroove, we got launched head long into developer bliss with a
new macbook pro (!), luxurious extra monitor and all the amenities right
off the bat.&lt;/p&gt;

&lt;p&gt;Possibly more important to the new employee experience than coming into
a sweet new workspace is coming in to a ROWE. There is no stressing out to
appear busy on your first day, no waiting for someone to tell you when
to go to lunch. There's only learning about Highgroove and getting up to
speed so that you are ready to work magic for your first client.&lt;/p&gt;

&lt;p&gt;Our experience was that even on our first day, we knew we will only be judged
by the results of our work and that we will be provided the tools to reach our
goals. That has made being a new employee for Highgroove different from any
other shop around.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>my second annual ruby conf report</title>
     <link href="http://highgroove.com/articles/2011/10/26/my-second-annual-ruby-conf-report.html" />
     <updated>2011-10-26T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/26/my-second-annual-ruby-conf-report.html</id>
     <content type="html">&lt;p&gt;RubyConf, ahhh Rubyconf.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.skitch.com/20111026-b1h7sfqrmrmsinffnj3h3qf6wt.png" alt="Ruby Conf 2011 Flyer" style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;How was it this year you ask?  To answer that question we must first address the
question:&lt;/p&gt;

&lt;p&gt;How was my first ruby conf?&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;To which an honest answer is, I couldn't really know at the time
(&lt;a href="http://highgroove.com/articles/2010/11/19/zomg-roflscale-rubyconf-or-why-you-missed-out.html"&gt;but you can read about my
impressions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;When you've done something only once, you don't have enough perspective to
judge effectively.  Thank goodness Matt and I wrote that post together.&lt;/p&gt;

&lt;p&gt;So, how did my initial impressions hold up?  First, let's see what happened this
year.&lt;/p&gt;

&lt;h2&gt;Matz's Keynote&lt;/h2&gt;

&lt;p&gt;Matz covered the continual maturation of ruby.  Companies hire ruby core
committers full time these days!  Awesome implementations annihilate
adversaries!&lt;/p&gt;

&lt;h2&gt;Big Data Enterprisy Analytics App and Ruby&lt;/h2&gt;

&lt;p&gt;Phusion rails ruby backed by Oracle and MS SQL Server for large healthcare
analytics?  Done!  Ruby conquers the enterprise!&lt;/p&gt;

&lt;h2&gt;Parallel GC Marking&lt;/h2&gt;

&lt;p&gt;The first attempt was too fine grained in its approach.&lt;/p&gt;

&lt;p&gt;Narihiro Nakamura attained great efficiency improvements by allowing threads to grab
tasks from one another when a thread 'stalled' on a large node (typically
a large array or hash).&lt;/p&gt;

&lt;h2&gt;How Getting Buff Can Make You a Better Rubyist&lt;/h2&gt;

&lt;p&gt;Rob Sanheim reviewed the importance of sleep and exercise, the power of
pomodoro, and the value of good long breaks away from the
computer.&lt;/p&gt;

&lt;h2&gt;LocalCommunity.Build, :through =&gt; Code Retreats&lt;/h2&gt;

&lt;p&gt;Here's one of the talks I looked forward to the most.  I love geeking out over
the internals of ruby or hearing war stories of processes and organizations
conquered but learning how to better spread the love?
&lt;a href="http://www.prakashmurthy.com/2011/09/rubyconf-2011-talk-about-code-retreats.html"&gt;Priceless&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Rails services in the walled garden&lt;/h2&gt;

&lt;p&gt;Map services to business verticals and keep them self contained and decoupled
for the win.  Centralize roles but federate the rules.  Keep centralized
services fast (~40ms) and implement caching.&lt;/p&gt;

&lt;p&gt;That concludes my notes for the first day.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;Where are the rest of my notes you ask?  Even though I was &lt;a href="http://highgroove.com/articles/2010/11/19/zomg-roflscale-rubyconf-or-why-you-missed-out.html"&gt;super
inspired&lt;/a&gt;,
I found myself strangely drained of energy the second day.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://instagr.am/p/OnaTn/"&gt;So good&lt;/a&gt;
&lt;a href="http://instagr.am/p/OnRAL/"&gt;yet, so tired&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;RubyConf 2011 Summary: Come for the talks, stay for the people.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Map Reduce Jobs in Ruby with Wukong</title>
     <link href="http://highgroove.com/articles/2011/10/25/map-reduce-jobs-in-ruby-with-wukong.html" />
     <updated>2011-10-25T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/25/map-reduce-jobs-in-ruby-with-wukong.html</id>
     <content type="html">&lt;p&gt;&lt;img src="http://www.philwhln.com/wp-content/uploads/2010/12/hadoop-ruby.png" alt="Hadoop + Ruby" style="float: right;" /&gt;&lt;/p&gt;

&lt;p&gt;I recently got to work on some really interesting, big data problems at Highgroove. One of our clients needed to record every api call and analyze specific time periods for averages and usage metrics. &lt;a href="http://hadoop.apache.org/"&gt;Hadoop&lt;/a&gt; fits this use case pretty well with a distributed file system and map reduce framework built in. But, I'll be honest, I wasn't too happy about having to write map reduce jobs in Java. While looking for alternatives I found &lt;a href="https://github.com/mrflip/wukong"&gt;Wukong&lt;/a&gt;; a gem that adds a Ruby wrapper around the &lt;a href="http://hadoop.apache.org/mapreduce/docs/current/streaming.html"&gt;Hadoop Streaming utility&lt;/a&gt;. Here's an example of how easy it makes writing map reduce jobs.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;




&lt;script src="https://gist.github.com/1315206.js"&gt;&lt;/script&gt;


&lt;p&gt;Now there are always trade offs. Streaming queries, especially to a Ruby script, are definitely slower than their pure Java counterparts. But, between the base startup time of any map reduce job (about 30 seconds) and the speed up from running all jobs in parallel across a cluster of workers, it's really not that bad and totally worth the improvements in readability and maintenance. Also, because this script runs over the entire cluster, you have to make sure that each machine has the right ruby version and and all necessary gems installed, but we easily solved this with a few lines in a &lt;a href="https://github.com/opscode/chef"&gt;Chef&lt;/a&gt; recipe.&lt;/p&gt;

&lt;p&gt;We've really only touched the surface of what is included with Wukong. There are plenty of different mapper and reducer classes depending on how you have your data structured and how you want to query it. With the script class provided by Wukong, you can run scripts across an entire Hadoop cluster with a single command. It even includes support for writing pig latin scripts in Ruby. So if you know Ruby and want to get involved with some big data projects, Wukong + Hadoop is a great way to get started.&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Tech Demo on the R Project for Statistical Computing</title>
     <link href="http://highgroove.com/articles/2011/10/21/tech-demo-on-the-r-project-for-statistical-computing.html" />
     <updated>2011-10-21T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/21/tech-demo-on-the-r-project-for-statistical-computing.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20111021-bbj3kq56uf3i6snenna9awybpy.png" align="right"&gt;&lt;/p&gt;

&lt;p&gt;This week's Tech Demo was on the &lt;a href="http://www.r-project.org/"&gt;R Project for Statistical Computing&lt;/a&gt; within Ruby.  The &lt;a href="https://sites.google.com/a/ddahl.org/rinruby-users/"&gt;RinRuby&lt;/a&gt; project  integrates the R interpreter in Ruby, exposing R's statistical routines and graphics (charting, plotting) from within Ruby.&lt;/p&gt;

&lt;p&gt;What would you do with R from within Ruby....&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Brian Stanwyck showed off some sample uses using Linear Discriminant Analysis for attempting to "guess" whether or not you are male or female, just by asking your height and weight.  It uses known "data" to learn and then extrapolates a guess based on the algorithm.&lt;/p&gt;

&lt;p&gt;This comes in super handy for some of our big data projects.  Doing a mean, standard deviation, or scatterplot is now a one-liner, and super fast.&lt;/p&gt;

&lt;p&gt;Another neat tool for our tool belt!&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Email Marketing for your Rails App Made Easy With Mailchimp</title>
     <link href="http://highgroove.com/articles/2011/10/18/email-marketing-for-your-rails-app-made-easy-with-mailchimp.html" />
     <updated>2011-10-18T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/18/email-marketing-for-your-rails-app-made-easy-with-mailchimp.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.mailchimp.com"&gt;&lt;img src="http://static.mailchimp.com/www/images/home/easy-email-newsletters-banner-png8.png" align="right" height="200" width="200" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you've got an awesome web application up and running. You want to keep your users engaged.  You could try to handle collecting emails, writing your own newsletters, managing the list, keeping content fresh, tracking who read your messages, and so on (and so on) -- all within your own app; however, there's a better way.  We recommend using &lt;a href="http://mailchimp.com"&gt;Mailchimp&lt;/a&gt;.  It's actually very simple to integrate Mailchimp into your own Ruby on Rails application.  Quick.  Easy.  &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt;.  Just the way we like it.&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;At &lt;a href="http://highgroove.com"&gt;Highgroove&lt;/a&gt;, we're notorious for not wanting to re-invent the wheel.  We LOVE using plugins, open-source libraries, ruby gems, and other external integrations in our apps.  Mailchimp.com is one of those external services we regularly rely on.&lt;/p&gt;

&lt;p&gt;A fairly common scenario is to collect user emails and send them a subscriber newsletter.  We need all the basics: collect the email itself, ensure the email is real, send the actual newsletter on a certain schedule, and allow users to opt-out or change their email profile settings.&lt;/p&gt;

&lt;p&gt;The first step to completing this online subscriber newsletter is to &lt;a href="http://www.mailchimp.com"&gt;signup for Mailchimp.com&lt;/a&gt;.  Once that is done, provide your API Key to us.&lt;/p&gt;

&lt;p&gt;The second step is to create a List within Mailchimp.  This List could be called "My Sites Newsletter", for example.&lt;/p&gt;

&lt;p&gt;The third step is to install the &lt;a href="https://github.com/amro/gibbon"&gt;Gibbon gem&lt;/a&gt;.  This is essentially a Ruby wrapper for &lt;a href="http://apidocs.mailchimp.com/"&gt;Mailchimp.com's own API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that we've taken care of all the setup of Mailchimp, the next couple of steps will show you just how amazing Mailchimp.com and Gibbon really are:&lt;/p&gt;

&lt;p&gt;On a basic level, all we need in the Rails application's code is an HTML form that collects an email address and some code within a controller method to save the submitted email address to Mailchimp.  We do this in two steps:&lt;/p&gt;

&lt;p&gt;First, create your form (this example is a HAML template):&lt;/p&gt;

&lt;script src="https://gist.github.com/1296606.js"&gt; &lt;/script&gt;


&lt;p&gt;Two, in your controller, add a line like this:&lt;/p&gt;

&lt;script src="https://gist.github.com/1296591.js"&gt; &lt;/script&gt;


&lt;p&gt;Once you've done the above, your Rails app is fully integrated with Mailchimp!  The content, frequency, and other settings that have to do with your newsletter are all controlled in Mailchimp's very simple interface.&lt;/p&gt;

&lt;p&gt;The only question you'll have left at this point is "What cool feature can we add next?"&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>Scaling Searching</title>
     <link href="http://highgroove.com/articles/2011/10/14/scaling-searching.html" />
     <updated>2011-10-14T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/14/scaling-searching.html</id>
     <content type="html">&lt;p&gt;&lt;a href="http://www.flickr.com/photos/eduardomaciel/4480835653/"&gt;&lt;img src="http://farm5.static.flickr.com/4003/4480835653_058b8e7520_m.jpg" align="right" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search is a hard problem, thankfully a lot of really smart people have spent a lot of time on it and come up with some awesome tools.  Most of our projects involve some kind of search functionality, and often tuning search indexes on the database server will get us enough performance to launch the minimum viable product.  But say we have 350,000 things that need fulltext search with ordering and boosting, or 50,000 things with extremely complex access controls in a high traffic environment that needs to search quickly and scale up to 10s of millions of things?  Here's a low-level look at some of the specific steps we've taken to make Rails scale. &lt;a href="http://canrailsscale.com/"&gt;Can rails scale?&lt;/a&gt;. We disagree.  Onward!&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Once we've exhausted the ability of the database layer, there are two paths to take. Even though people call me 'old school' for it, I like to start with caching things in memcache. I'll add &lt;a href="https://github.com/mperham/dalli"&gt;dalli&lt;/a&gt; to my project, set it up as the Rails.cache store, and get started. This begins as a pretty simple method; Here's an example of caching something expensive:&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=model_1.rb"&gt;&lt;/script&gt;


&lt;p&gt;This works great for things that are expensive to calculate, but has two problems. It doesn't speed up actual searching, and when the cache is cold, the expensive calculation is inline and we have to start to do crazy things like this:&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=model_2.rb"&gt;&lt;/script&gt;


&lt;p&gt;'.delay' is a magic method provided by &lt;a href="https://github.com/tobi/delayed_job"&gt;delayed_job&lt;/a&gt; which enqueues this expensive computation as a background job. All those 'force' parameters are there to force not using the cache which makes debugging and testing a lot easier, because this get's very crazy very fast when you have 10s of different things you're caching, some of which include results from other cached values.  Typically it makes sense for some cached things to be stored in the cache permanently, with code that updates them nightly or whenever their values change, as an empty cache is pretty useless when you're counting on it.&lt;/p&gt;

&lt;p&gt;Unfortunately, it's very hard to get caching right and you will have page loads that take 10s of seconds due to things not being cached when you need them. Also, queuing up 1000s of delayed jobs with .delay (due to cache being cold) means 1000s of database inserts which isn't quick either! Something like &lt;a href="https://github.com/defunkt/resque"&gt;resque&lt;/a&gt; will help a bit, but it's a tiny bit more involved to get running than delayed_job. Perhaps most annoying,  things can get deleted from under you so you have to handle the possibility that an id you are using may no longer exist. Here's one way of doing that:&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=controller.rb"&gt;&lt;/script&gt;




&lt;script src="https://gist.github.com/1288116.js?file=view.html.slim"&gt;&lt;/script&gt;


&lt;p&gt;So you've gotten to this point, caching isn't enough, and searching needs to happen and be fast. Enter &lt;a href="http://lucene.apache.org/solr/"&gt;Solr&lt;/a&gt; and &lt;a href="https://github.com/sunspot/sunspot"&gt;sunspot&lt;/a&gt; (Which our very own &lt;a href="http://highgroove.com/about/andy.html"&gt;Andy Lindeman&lt;/a&gt; works on!). Adding these to your project is explained very well in the sunspot documentation, and if your app is deployed on &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; like many of ours are, there's a reasonably priced &lt;a href="http://addons.heroku.com/websolr"&gt;websolr addon&lt;/a&gt; that Just Works with the sunspot gem. Adding it to a model is very straightforward&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=model_searchable.rb"&gt;&lt;/script&gt;


&lt;p&gt;Searching is also pretty straightforward, but this usage is a little more complex in the basics we want to make sure that all of the connection ids return both match the parameters and are in a potentially huge set of IDs that we are allowed to access.&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=model_searching.rb"&gt;&lt;/script&gt;


&lt;p&gt;Solr searching is &lt;em&gt;very&lt;/em&gt; fast, especially when compared to bigger datasets in postgres, and using it's search_ids method (instead of search) prevents loading all of the objects so that we can rely on the controller/view pattern above for loading only the objects we are displaying (pagination of the resulting array happens in the actual use case).  This, combined with Rails 3.1's &lt;a href="https://github.com/rails/rails/blob/master/activerecord/lib/active_record/identity_map.rb"&gt;Identity Map&lt;/a&gt; feature or something similar means that we can serve pages and pages of search results very quickly (200ms or so), doing fulltext matching, and displaying information from within the objects, all without having to hit the database.&lt;/p&gt;

&lt;p&gt;Everything Just Works on Heroku, and for running things locally, theres a Procfile and &lt;a href="https://github.com/ddollar/foreman"&gt;foreman&lt;/a&gt; for that:&lt;/p&gt;

&lt;script src="https://gist.github.com/1288116.js?file=Procfile"&gt;&lt;/script&gt;


&lt;p&gt;Whats your secret to scaling up?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>The Sales Playbook</title>
     <link href="http://highgroove.com/articles/2011/10/11/the-sales-playbook.html" />
     <updated>2011-10-11T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/11/the-sales-playbook.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20111012-1m713q3n83cqas3yncjxhts29a.png" align="right" /&gt;&lt;/p&gt;

&lt;p&gt;Today, I attended a workshop from the Atlanta &lt;a href="http://www.eonetwork.org/"&gt;EO&lt;/a&gt; chapter led by the charismatic Jim Ryerson of &lt;a href="http://www.salesoctane.com/"&gt;Sales Octane&lt;/a&gt; on improving your sales process, through the use of a Sales Playbook. I'll admit, I've always been pretty good at selling (it helps to have an awesome team and product behind you), but the Sales Playbook we have (and that went through a ton of editing today) makes it even easier.&lt;/p&gt;

&lt;p&gt;What's in a Sales Playbook? Ours contains things like:&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;ul&gt;
&lt;li&gt;our Elevator Pitch and an extended (longer) version&lt;/li&gt;
&lt;li&gt;our Sales Map -- a flowchart of all the steps we take to close a deal&lt;/li&gt;
&lt;li&gt;explanations, scenarios, scripts, and stories from items on the Sales Map&lt;/li&gt;
&lt;li&gt;how we prospect -- what associations and networking events we attend&lt;/li&gt;
&lt;li&gt;how we research potential clients&lt;/li&gt;
&lt;li&gt;a list of the common objections (and some fodder for consideration)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Just simply writing down the process provides many benefits. I have a hard time saying no, so having a process to abide by, makes it easy to qualify (or not qualify) incoming leads. Also, since everyone at Highgroove can see the process, they know exactly how it's done, and can help improve it. It provides a fantastic answer to a client's question "what's the next step?" It provides clarity to everyone at Highgroove on how projects end up ready to start iterating. It takes the pressure off the "sale" and makes it fun and enjoyable.&lt;/p&gt;

&lt;p&gt;We even make part of our Sales Process completely transparent to clients.  At the bottom of every email, we bullet point out the next steps in the process, so everyone knows what's next.&lt;/p&gt;

&lt;p&gt;Do you have a Sales Playbook, and if so, what's in it?&lt;/p&gt;
</content>
   </entry>
 
   <entry>
     <title>If you aren't getting burned...</title>
     <link href="http://highgroove.com/articles/2011/10/05/if-you-aren%27t-getting-burned.html" />
     <updated>2011-10-05T00:00:00-04:00</updated>
     <id>http://highgroove.com/articles/2011/10/05/if-you-aren%27t-getting-burned.html</id>
     <content type="html">&lt;p&gt;&lt;img src="https://img.skitch.com/20111005-t7ga692gc5s4cxd6p8edaiehfk.png" align="right" /&gt;&lt;/p&gt;

&lt;p&gt;Highgroove's "bias towards action" rallying cry is no secret, and we try to abide by that rule whenever we can, whether we're deploying or choosing where to go for lunch. An important corollary is that we try to bias towards &lt;em&gt;making mistakes earlier&lt;/em&gt; rather than later, too. A fellow Highgroover captured it well by saying: "If you aren't getting burned, you need to play with fire more."&lt;/p&gt;

&lt;!-- -**-END-**- --&gt;


&lt;p&gt;Learning what breaks a new system helps developers get a feel for when heavier infrastructure might be required (e.g., implementing background jobs if server-side code starts becoming too intensive).  And it's part of why we encourage new developers to &lt;a href="http://highgroove.com/articles/2011/06/07/deploy-code-your-first-day.html"&gt;deploy code on the first day&lt;/a&gt;: it's better to learn how to fix production while you're getting situated than when there might be no one around at the moment (especially in a ROWE).&lt;/p&gt;

&lt;p&gt;But finding out when your system &lt;em&gt;doesn't&lt;/em&gt; break can be just as important. I've discovered security issues in the past by using unsafe code I "knew" shouldn't work as part of an initial naïve solution or experiment.&lt;/p&gt;

&lt;p&gt;Well-developed test suites, of course, are what make all of this possible, by telling you exactly what has broken and where. It's also what made me initially come around to TDD; writing tests first means you don't bias your own thinking to the code you've written, making it easier to consider what "breaking" a model or controller (for example) should look like in a test.&lt;/p&gt;

&lt;p&gt;Do you encourage experimentation and "failing fast"?  How?&lt;/p&gt;
</content>
   </entry>
 

</feed>

