Friday, May 1, 2009

A day the Hashrocket way

Two weeks ago, I had the awesome opportunity to spend a day at Hashrocket’s office. Hashrocket is a consultancy company from Jacksonville, FL, specializing in Ruby on Rails software development. It is led by Ruby on Rails community well-know and book author Obie Fernandez.

Thanks to their open nature and their utilities such as presentations, posts, tweets and videos, I already knew a lot about “The Hashrocket Way”. I must say though that I didn’t really believe in some of their techniques and practices, mostly because I haven’t tried them out. ;) Therefore the visit since I like to learn and am open to change. (Who isn’t?)

With this post I’m sharing what I’ve learned during my visit at Hashrocket. I’m writing it in the form of Hashrocket’s way versus My way of developing software. Only a few sections are Ruby on Rails specific.

To give you a quick impression on how my day at Hashrocket started, look at the following picture.

This is actually the way to work of some of the Hashrocket developers. That’s hard to beat.

Just in time at 9 am, I arrived with Hashrocket’s new Designer Andrew Maier (who’s working on an awesome new Hashrocket site) for the daily stand-up meeting at Hashrocket's office. It’s a short kick-off meeting for the day. We talked a little about who’s going to work on what, about a few technical things from the day before, I introduced myself to Hashrocket’s people and Hashrocket’s project manager Sal assigned me Matt Remsik as my pair programming partner for the day. More on that later.

Let’s get started with Hashrocket’s way versus My way ...

Always pairing vs. Occasional pairing

Hashrocket is a (maybe the only) well-known coding shop that practices full-time pair programming . I was wondering myself if that’s really worth the money from the stakeholders side and worth the time from the coders side.

The way I looked at pair programming before coming to Hashrocket was that pairing is a coding technique to overcome a developer’s block, get a new project rolling or designing the implementation of a new feature. Most of the time though, a developer should embrace his flows (between the pairing sessions) and get things done. Ideally, the other developer gets other things done during the same time. Summed up, this would suggest to be a faster technique for moving forward with software development.

Ish don’t think so anymore. At least, I don’t believe anymore that it’s that easy to calculate. The reason is that I was pretty surprised on how often me and my pair Matt Remsik called on each other's action. With called I’m referring to giving ideas, suggesting better solutions, correcting and optimizing code.

This results in my new impression that situations where a pair can help, occur more randomly and often than I thought, even or especially in a developer’s flow and not only during the usually suspects such as developer’s block and starting a new project or feature.

This impression should be taken with a grain of salt though, since this is my impression from only a few hours. Unfortunately, I don’t have a pair at my side right now to test pairing over a longer period of time.

Pairing locally vs. Pairing remotely

Today, a lot of people work together remotely such as me with my peer Samuel Goebert . We're using remote screensharing (via Teamviewer or iChat ) and a remote audio connection (via Skype or iChat ). Somehow I had in my mind that pairing locally means sharing one keyboard, one (small) screen and rolling around with chairs. Therefore, remote pairing has been a clear winner for me, since both peers can easily access their keyboard, their screen and don't need to roll around when switching sides. Well, turned out that Hashrocket has a very cool setup which addresses all three of these issues. They use two external USB keyboards, one huge (30”) screen and two chairs side-by-side. You can see that in this video and in this one.

I talked with Matt Remsik about their setup, which I once saw, with two huge screens, one for each peer. He made an interesting point by saying that they felt a big difference between working on two separate or one screen. He said one screen helps to communicate since you also can take the other ones gestures in account. So, basically, you can easier notice where the other one is looking or pointing at.

Working in an open office vs. Working in a quite room

My opinion was that it makes more sense to put each pair in a separate room. Especially if you have multiple pairs in a room (instead of single developers), it can get a little noisy as you can sometimes tell from Hashrocket's videos . ;)

I won an interesting insight on this topic which in fact weakens my standpoint. I assumed that a lot of pairs in one room is worse in respect of higher distraction rate than a lot of single developers in one room. It turned out to be the other way. Noise (conversations, videos, sounds) from other teams feel less distracting in a room with pairs than in a room of single developers.

To explain that, Matt told me about a very interesting cocktail hour theory, which is that when talking at a bar or cocktail party to someone, you can concentrate on that conversation fine even though there's a lot of noise from other people and music in the background. The cool thing about your ear and brain is, that it still can filter interesting bits of information out of that background noise. So if somebody at that party mentions a movie or a place you just have seen or visited, you can catch that up and decide if you want to join that conversion or not.

The same counts for the office. If somebody for example mentions Rails on Google App Engine or a specific problem when upgrading to Rails 2.3 and you have been reading about it or are interested in it, you quickly can join the conversion and learn. Most of the times so, the other pairs are talking about their current code and task, which doesn't interest and therefore distract you from your conversation with your pair, and pair programming is a lot about conversation.

Working in an office vs. Working at home

I’m often wondering about what gives a lonely freelancer the ultimate satisfaction and highest productivity while working. ;) So the work environment plays an important part. I have tried working at an office with coworkers as an employee, working at an office alone as a freelancer and working alone from home. I unfortunately haven’t tried sharing office space with other freelancer yet, though.

Hashrocket actually makes you feel a lot like you’re a freelancer and sharing office space with others. That’s definitely a big plus and eventually helps satisfaction and productivity. There aren’t many companies and offices out there where you can play a bit of ping pong during your working hours.

Anyway, I have been working alone from home lately. Sometimes I wouldn’t mind to get out and breath a little office atmosphere. I guess a mixture might be the best (for me), since I wouldn’t like to have to go to an office every day.

Matt Linderman from 37signals also just reminded me to take in account the time you lose every day and week for your commute when working outside of home. Also, Hashrocket’s online book club is bringing you an office with smart programmers to your home every Tuesday to kind catch up with the missing office atmosphere. After all, working “on the road” also might not be a bad idea.

Vim vs. Textmate

At the stand up meeting in the morning I mentioned that I’m using Textmate as my editor for Rails projects. Gestures of some attendees let me know that I’m old-school (or new-school?). Anyway, it turned out that Hashrocket’s editor of choice is Vim (with a rails.vim plugin from their own Tim Pope).

I could see the advantages such as vertical split screen (i.e. model file on the left, model’s spec file on the right), faster copying & pasting and having all in the console. Together with the keyboard issue, about which I’m talking in the next section, this has admittedly giving me a kind of hard time throughout the day though, since I just wasn’t used to it. Anyway, vim will be worth a try.

English Keyboard vs. German Keyboard

I’m German and I have been using German keyboards throughout my life time. Unfortunately, they don’t use German keyboards in America. ;) So typing y and z’s or Ruby common characters _, @ and ? was a little tricky and time intensive.

Coincidentally, I had a German external Apple keyboard with me.
Unfortunately, Apple doesn’t support the most needed feature of supporting different keyboard layouts for two different USB keyboards. What a flaw! ;) So, a German keyboard with an English keyboard layout wasn’t making things better and I returned to the English keyboard.

Git vs. Svn

I'm (still) using Subversion for my source code version control for internal projects. (Git users, you can roll your eyes now, I don’t see it anyway. ;)) It’s not because I live behind a mountain (I actually do). I noticed the git storm through my internet connection and I have been using git for a few open source projects of mine.

Internally, I still like Subversion, though. Especially its simplicity and usability. In git, you can do the same things in 5 different ways. In Subversion there’s practically only one command for each action. Maybe these two points are not technically correct, it’s just my feeling. Also, I somehow like to have a linear and non-manipulated history. Subversion makes sure of that.

Moreover, I feel like that some people switched to git because it’s easier to switch between branches. After all, it’s not Subversion’s fault, they just didn’t know about the svn switch command.

Also, the latest Subversion releases (1.5 and 1.6) introduced some git-like features that makes it actually even more difficult for me to find reasons to switch to git.

For example, since version 1.5 Subversion keeps track of merges. No need to specify revisions by hand when merging anymore. Also, since version 1.6 Subversion allows relative remote paths.

So I’m pretty cool with the following commands I use daily:
# merge latest trunk into a branch
svn merge ^/trunk

# merge a branch into trunk
svn merge --reintegrate ^/branches/feature-x

# tag a version
svn cp ^/trunk ^/tags/version-x

Ok, enough Subversion love. After all, I don’t want to claim that I’ll never end up with using git someday. One thing that sometimes bothers me about Subversion are slow merges. So speed may sell git for me, as for many others I guess, too.

Anyway, Hashrocket uses git. In the next chapter Their RSpec practices vs. My RSpec practices I discuss one git-ish workflow they follow, which wouldn’t be possible with Subversion.

One last cool tidbit from Hashrocket regarding source code control: After pair programming sessions, they actually commit in the names of both programmers, which is cool since you actually see the pairs in your version history. They also have a wildcard email account that accepts emails in the following format prog1+prog2@email, which you assign in git to the actually commit names.

Their RSpec practices vs. My RSpec practices

For model and controller testing, Hashrocket uses RSpec. So do I. For testing with data, Hashrocket uses Factory Girl (instead of Mocks and Fixtures). So do I, too. In a later section I’ll talk about integration testing.

From the videos you can tell that they are using autotest sometimes. I stopped using it since it got kind of annoying.

There’re basically two things I learned regarding RSpec. (I’m sure there’s more to learn, but it was only one day.)

The first one regards sorting and arranging of the RSpec contexts. I’m wondering sometimes if I should just put the new context for let’s say a new method at the end of the spec file. My pair, Matt Remsik, sorts them the same as the methods are defined in the corresponding model or controller file. This may especially helpful when you have split screen as I mentioned in the previous Vim vs. Textmate section.

The second thing we were talking about was about their workflow of committing and running full specs. They commit first and then run the full specs, which can take a couple of minutes. The git-ish trick here is, that if the spec run reveals regressions bugs, they fix them and merge these fixes via the git rebase command into the last commit. The goal is to have an atomic working code commit for each story or feature they have been working on. The reason is to be able to easily revert these commits which represent features or stories. However, I think that this is a kind of belief from an ideal world and in my experience removing code is almost always preferred instead of reverting a commit. Matt Remsik agreed on that one, too.

After all, I wonder if rewriting history is necessary at all and actually helpful. One argument from Hashrocket was, though, that their continuous integration tool is checking every commit, therefore, every commit should be working code, even in branches. I agree with that on the master branch, but myself likes to be able to commit to development branches non-working code. That’s actually why I belief you split the development of bigger features into branches.

jQuery vs. Prototype (vs. Ext Core)

I remember, some time ago Hashrocket switched from Prototype JS to jQuery. Hashrocket’s boss Obie mentioned it in this blog post . (Damn, I just noticed Obie used the same “vs.” style in his blog post, now mine looks like a copy cat. Whatever, this blog post is worth a look, since it has the same style but different content.)

Unfortunately, I forgot to talk about their experience with jQuery and reasons for the switch. Looks like I have to visit them again. ;)

Anyway, it will be interesting to see how the recently released Ext Core is mixing up the market. It will definitely be my choice of lightweight Javascript lib for future projects, since I like Ext’s API and clean code and am familiar with it from the Ext JS lib.

Cucumber-based GUI testing vs. Ruby Selenium GUI testing

I didn’t actually see Hashrocket’s Cucumber GUI tests in action (I’m sure I could have though, if I would have remembered to ask) but still learned about a new gem: Culerity, which “integrates Cucumber and Celerity in order to test your application's full stack including Javascript.”

Celerity (not the just mentioned Culerity) is “a JRuby wrapper around HtmlUnit – a headless Java browser with JavaScript support.” You always can use Cucumber with Selenium, too, but the tests have to run in the actual browser, which can be a bit slow.

I heard from the Hashrocket crew though, that Culerity or Celerity have some issues with testing Javascript sites. Basically there seems to be a caching issue, which is why they are still “forced” to use Selenium.

After all, my opinion is that Selenium isn’t that bad at all. It surely doesn’t scale well, but what does? ;) In my case, it actually runs pretty fast (remember to GUI test your Rails app in production mode). Also you already can write your Selenium tests in Ruby and additionally I wrote my own little Selenium helpers to help me with testing Ext JS apps, about which I’ll blog shortly.

Pivotal Tracker vs. Basecamp

I knew that Hashrocket uses Pivotal Tracker and I have seen it before. But the interface didn’t really make me love it at the first sight. Seeing it in action during my visit at Hashrocket made the trick, though. I have been using Basecamp with my clients for a while (only the todo section, though). Basecamp definitely helps to communicate and collect open tasks. It gets a little messy though when trying to prioritize and plan. Certainly you can make todo lists for each iteration, add estimate points and status flags to the todo item names and prioritize by drag & drop in Basecamp. But you have to do all that manually, again and again.

Pivotal Tracker’s user interface and automatization features simplify these workflows.

Depending on your virtual velocity, Pivotal Tracker plans your iterations itself. The vertical view split of your different “todo lists” eases dragging & dropping of items. (Try to drag &

drop an item in Basecamp throughout a page break. Also try to drop an item in an empty todo list. The first is tricky, the latter not possible.) An item’s status is easily visibly through their Start, Finish, Deliver, Accept & Reject Buttons.

When I came home from my trip to Hashrocket, my question was, what needs to be done for the next iteration on my current projects. Basecamp didn’t tell me, so I switched to Pivotal Tracker right away, since it tells you automatically. (Manually copied & pasted todo items and comments from Basecamp to Pivotal Tracker, don’t know about a migration client.)

So far, I’m very happy with Pivotal Tracker. Here’s a good link that summarizes some other advantages of Pivotal Tracker. Also, just a few days ago, Hashrocket posted a video about how they use Pivotal Tracker, check it out.

One thing I’m missing right now is an integrated time tracker, or a time tracker that integrates with Pivotal Tracker. Anybody knows one?

Bonus: Their office view in Jacksonville vs. My office view in Dubai :)







I round this blog post up with a kind of fun comparison. After all it influences your work environment.

For a year I worked at an office in Dubai, UAE, which was almost as close to the beach as Haskrocket’s office. But Hashrocket wins this comparison (as many others), since they actually can see the beach (I couldn’t, only a little bit blue of the sea between the Palm Island’s leaves and construction sites). Also the Burj Al Arab view has been ruined by another highrise by now. Oh, and as almost its name suggests, you can see Space Shuttle launches from Hashrocket’s place.

Résumé

It was a really awesome day. I wouldn’t want to miss that day in my life and career. I didn’t actually feel like a guest, rather like a Hashtronaut a.k.a. a developer working at Hashrocket. :)

I hope I could pass along some of the value I enjoyed be receiving from my day at Hashrocket with this blog post to other known and unknown people out there in the cloud.

My exciting day at Hashrocket ended with a very productive sit-down meeting with I few of their developers.

Thanks a million to my pair @veezus , my project managers @beebe4 and @salc1219, my housemate @andrewmaier, my colleagues @sandrot, @l4rk, @tpope, @cgrusden, @the_mug, @wesgibbs, Jen, Les (and all I forgot) and last but not least the boss @obie! :)