Closet Coder

I work in my closet. I code. Yep.

Pairing Post Mortem - @stuartrexking - Cane Extension

| Comments

Last night’s pair session was with @stuartrexking - a very experienced developer and technologist currently working at a really neat company called Antipodean Labs. It seems like he’s got a great handle on solving problems and staying maintainable.

We started off by trying to decide what to do. I’m increasingly convinced this is the possibly the hardest part of remote pairing with people who aren’t part of your company. You don’t have a predefined complex project you both find interest in, so the most likely shared interests are either meta problems or highly common ones. Highly common ones are very visible and difficult to find low hanging fruit for. The meta problems are good to solve, but somehow feel like they are less valuable than the “real” problems. Maybe this is just a feeling I have.

We eventually decided to make an extension to Cane to count the number of lines in a method. We started off by writing an acceptance test, which turned out to be much easier than the implementation. Once we got that test running, we started running into problems with Cane’s architecture. Cane doesn’t pass in a file to a “filter”, but rather requires that you parse a glob yourself. This seems like it doesn’t scale well. Running into this problem made us rethink our position entirely and by that point, I was a bit too tired and worn out from other things that happened this week. We put our project on hold and decided to come back to it next time.

I still have takeaways from this session, even though by most accounts we wouldn’t consider it a “success” in terms of producing something or completing a task.

Takeaways

  • I like writing an acceptance test that “wraps” a bunch of unit testing. The unit tests end up driving your coding decisions and the acceptance test makes sure you’re driving toward the feature you intended.
    • Acceptance test says ‘this is my finished feature in a black box’
    • Unit tests drive individual methods and behaviors and decisions to ge that acceptance test to pass.
  • Deciding on a project is probably best outside of the context of the pairing. Shoot ideas back and forth prior to so little time is wasted once you’re “on” and ready to pair.
  • :bp in VIM rotates to the previous buffer. Nice.
  • Pairing with people much brighter than myself makes me want to improve. YMMV, but I’d encourage you to try to think that way, even if it’s unnatural at first.

I really enjoyed pairing with Stuart and hope we get to finish up our project soon. Looking foward to more time with him in the near future.

On to the next pairing session…

Steps for a Beginner to Learn Ruby

| Comments

Ruby is not Rails. Learn Ruby first.

  • Get rbenv (preferred) or rvm installed with Ruby 1.8.7, 1.9.3 and 2.0
  • Write Hello World and run it
hello_world.rb
1
puts "Hello World"
  • Go through the Ruby Koans (simplest with 1.8.7)
  • Go through some TDD exercises
  • Code a simple ruby script that solves a problem you have, like…
    • Add a TODO to a file
    • Print out the date in another time zone
    • Tell you how many days until…
    • Perform some repetative task related to your environment
    • Display something silly for your kids

Ruby is not Rails. You do not need to learn all the “magic” of Rails to learn the awesome of Ruby. Spend some time and get where you can really drive a script and solve a simple problem. Doing this will get you far beyond a beginning Rails developer. You simply have to learn the magic incantations of Rails to be able to develop web apps after that. And those incantations won’t be nearly as scary.

Pairing Post Mortem - @_zph - Meta Pull Requests

| Comments

I had a great #pairwithme session with @_zph. Always a pleasure to talk to him and solve a problem together.

Setup

Experience

We wanted to add the feature to gh-auth so you could pass a –path or –user argument to it. Because we’re good developers, we started off by coding the acceptance test. We discussed the merits of how to write good tests and whether to follow convetions within a gem authored by someone else or do things ‘the right way’ – according to whatever coding religion you follow. Eventually we decided on sticking to the conventions of the gem while trying to improve–but not radically change–the tests/testing that we touched. From there, we dove down into the implementation and unit tests and drove through until we had the –path argument working. Along the way we did a little refactoring to use the OptionParser instead of requiring a specific ordering of options.

Within an hour and a half we had successfully test driven a new feature and gotten it working. We aliased –user to basically be a shortcut for –path, but that was it.

Takeaways

  • Solving real problems teaches you very different things than solving exercises.
  • A good test suite is crucial for getting people to be able to contribute to your library
  • Convention should probably trump your coding religion in 90% of the cases. As with any religion, introduce it in small pieces when it comes up.
  • Having a near ready pull-request to show for a pairing session felt amazing.
  • OptionParser is very useful.

I am looking forward to more and more OSS contributions through pairing. I’m almost thinking I need to ‘invent’ a widly useful (not necessarily used) gem to be able to pull out when I’m pairing to get the maximum effect. Super cool.

On to the next pairing session…

Pairing Post Mortem - @Shicholas - String Calculator

| Comments

Last night I had a great pairing with @Shicholas working on the String Calculator kata.

Setup

We again used TMUX + VIM, even though Nick wasn’t very familiar with VIM. Based on his experience, I think this might be the best way to learn VIM since you have someone guiding you through. You won’t pick up on everything, but you’ll learn a handful of new things each time.

Exercise

We went through each of the different rules and ping ponged back and forth. It was a struggle to do the simplest possible thing every time, and really let the tests DRIVE your development. Your developer brain wants to generalize the solution to a problem, but the strength of TDD is keeping your actual solution as simple as possible. Developers are notorious for over complicating things and over desigining.

We found that refactoring for readability vs. duplication/maintainability was in conflict. Specifically when we needed to split a string to look for a delimiter and then keep the remainder to parse later. We could have put that code in an initializer, or a helper–but we would have either divorced the implementation from where it was used or made redundent calls. We opted for redundent calls until it became a problem.

Takeaways

  • The strength of TDD is keeping your solution as simple as possible
  • Refactoring is really dealing with tradeoffs and trying to figure out the best way given a set of circumstances. It’s an art not a science.
  • It’s easy to teach/learn VIM when you’re pairing as long as people have a basic understanding of Insert/Command mode
  • Ruby 2.0 has this thing called refinements that sound like a good idea, but probably aren’t ready for prime time yet. We didn’t experiment with them… I just found out about them because we did a tiny monkey patch of String for the exercise.

I’m really starting to see how powerful real TDD is, especially in the context of pairing. I hope I can see this further as the pairings I participate in go past exercises and onto real world stuff. I’m excited to see how much my TDD improves.

On to the next pairing session…

Pairing Post Mortem - @willpragnell - Overseas TDD

| Comments

I had my first pairing session with @willpragnell today. He’s a smart guy and my first European pair partner. It was a pleasure to talk to him about his iOS and Ruby experience and I picked up on a lot of little things from our pairing session together.

Setup

The Session

We set a couple of goals out for the beginning. We both wanted to learn more of RSpec’s new syntax and we wanted to really adhear to the TDD principle of doing the most simple thing next.

We spent about 45 minutes implementing TicTacToe and came up with a different implementation than I’ve ever done before. One of the reasons was that we started off by writing our pending specs first and we had a lot of discussion for HOW to solve the problem. TDD is the least brittle and most helpful when you focus on what something does rather than worrying about how it does it. Oddly, this is difficult sometimes to agree on. Does Tic Tac Toe, the game, alternate players, or is that just how people play it? Making these kinds of decisions with your tests makes a difference in how you implement.

Takeaways

  • Think a lot about your tests: they shape your design, so badly designed tests probably result in bad design.
  • It made a difference in how we were going to design the tests when we decided this was going to be a shell for a UI. Think of how your code will be consumed
  • I like RSpecs new syntax, especially since it doesn’t pollute the object method space: expect(game.play(5)).to be_true
  • in vim autocompletes a whole line
  • There is nothing like pairing to make you realize how much every developer loves to cusomize their editor/environment.

Great session! I look forwarding to my next with @willpragnell

UPDATE - afterwards, I really liked where this was going. I spent a little time and tried to finish out the implementation. It’s my favorite implementation of TicTacToe because it’s so simple. Thinking of the UI, but coding the tests just under it made it easy to drive and then super simple to throw on a CLI that worked perfectly.

On to the next pairing session…

Pairing Post Mortem - @hinbody - Attacking Open Source Is Hard

| Comments

The easiest things to pair on are little tasks that you both understand and can be easily “completed” within a 1-2 hour pairing session. Unfortunately, Tic Tac Toe, Conway’s Game of Life and Bowling become stale quickly. It’s not that they don’t have valuable things to teach you, but you can’t pair with the same people over and over again just doing those problems. Eventually you need to dive into a real project.

At that point, you have two options:

  1. Work on a project one of you is authoring
    • Open Source Gem (widely accepted)
    • Closed Source (some people feel as though they should be paid for working on a commercial product)
  2. Work on an Open Source project with the goal of submitting a pull request.

The second option is more viable for most of the pairing community. Not everyone will have an OSS project they feel is worth pairing on, and not everyone can get permission to let a random pair work on their closed source project. Even with those two options crossed off, you can also both learn by reading other code and solving other people’s issues.

In my latest pairing with @hinbody, we tried our hand at Spree and learned a few things along the way.

Observations

We started off by looking at Spree’s issues and trying to select one that looked like somewhat low hanging fruit

  • It was hard to find low hanging fruit.
  • Pull-requests mixed in with the issues made it more difficult to find what we wanted.
  • Lack of familiarity with the product probably multiplied the difficulty.

After we finally found what looked like a very simple documation change, we dug in a bit.

  • We wanted to see code work that indicated what the documentation should be, so we tried to get the tests to work.
  • Most of our pairing time was spent trying to get the environment set up so that we could run specs.
  • The issue and comments did not seem to match what we saw in the code.

Takeaways

  • Having the code you’re going to work on checked out and tests running/passing saves a lot of time.
  • Picking an issue is hard. Being familiar with the project/domain makes a big difference.
  • Picking an issue is part of the learning process. Just digging in to figure out what an issue was talking about gave us a better feeling about that specific part of the project.

Not the most productive pairing session, but still worthwhile because we learned a bit about how to begin digging into Open Source

On to the next pairing session…

Watch and Learn

| Comments

I’ve now been pairing with several people a week for the last few weeks. Even over that short period of time, I’ve seen a pattern emerge:

If you watch someone else (of any skill level) and pay attention, you will learn.

When I’m watching others, I tend to be thinking of what I’d do in their situation, but sometimes just observing very simple things a user does – a VIM action, a command line script, an obscure API call, a rare tool – these are the details that change you in the small over time. This same principle is why counselors tell you to actively listen to your spouse – hear what they’re saying instead of just thinking of what you’re about to say. Sometimes you pick up on things they might not be able to vocalize themselves. Sometimes you pick up on emotions you would be too busy to notice otherwise. Actively listening in any relationship involves shutting up and noticing the details–it just happens to be true when you’re pair programming as well.

So the next time you’re pairing, watch closely, ask real questions, and learn.

Pairing Post Mortem - @mattr_ - Pending Specs and Assertions First

| Comments

Today I paired with @mattr_ and got quite a bit of good input regarding how to attack a problem and write tests. Matt is a super smart guy who has really absorbed some of the fundamentals of TDD and it shows through his ability to break down a problem.

Setup

  • TMUX & VIM on my box
  • Conway’s Game of Life as an exercise

Process

When implementing the game of life, we started off looking at the problem on Wikipedia and found the 4 rules. I immediately started writing the first test when Matt noted that he liked to write all the specs he knows of as pending specs right at the beginning. Then he can really plow forward and know what’s next. He also noted that he likes to be able to write the assertion first, based on the test, and then build the test up from there. I felt the lightbulb go off when he pointed these two things out. When I’ve struggled to find the test or figure out how to test something, usually it’s because I can’t figure out how to get to the assertion, and that really comes down to not testing the right thing.

After talking through those points, we went through the TDD process for the Cells and moved on to the actual Game (interaction of Cells). Things got interesting here since we started noticing how divorced our Cells were from our Game itself. We decided we wanted to use a Graph of cells to really implement the game when we ran out of time. It was great to see how the tests were pointing us towards the problems in our code.

Takeaways

  • Write as many pending specs as you can first
  • Write your assertions first
  • ???
  • Unicorns and Rainbows.

Looking forward to pairing with @mattr_ again. He was very knowledgable and good to work with.

On to the next pairing session…

Pairing Post Mortem - the Mistake

| Comments

"How'd I do? I passed! But I failed! Yeah!"
"Well, then I'm happy and sad for you."

Last night I made a mistake. In an effort to continue pairing with people I really enjoyed pairing with, I scheduled 2 pairing sessions for the same evening. I left 30 minutes between them, I prepared as I should… but I was stressed and it made both sessions worse.

I struggled with our first session because I was focusing on getting things done rather than teaching and learning. This made me a pairing hog and I feel bad for it. My pair even said “I feel like you’re doing everything and I’m not helping.” I tried to assuage his concerns by saying “the discussion beforehand was a big part of pairing…” –which it was. But it doesn’t excuse my taking control. We could have easily gone back and forth and still finished the feature.

In my second session, I paired with someone that had low bandwidth, which made it difficult to understand his audio. We used ScreenHero as well, which ate up more bandwidth. We easily spent 30 minutes of our hour session just getting set up. By that point, I felt spent and I was frustrated with the audio problems. This made me less excited about a pairing I was looking forward to and put a bit of a damper on the rest of our time. I feel certain that it would not have been a problem if I was not already a bit drained.

So, lesson learned: There is more than just the time blocked off on your calendar that goes into a pairing session. You need decompression time for you, for the benefit of the people you’re pairing with, and for your family and friends. I’ll be making sure not to schedule multiple pairs close together going forward.

Quick Script for TMUX Pair Sessions

| Comments

Update 2013-06-14: Improved the script, removing the github-auth dependency, some of the OS X dependencies, and added firewall punch-through (user specific) and ssh-command with external IP auto-copy to clipboard

I wanted a quick and easy way to set up a new TMUX session with a brand new pair, so I came up with this:

~/bin/pair-session
1
2
3
4
5
6
7
#!/bin/sh
gh-auth add $1
sudo cp ~/.ssh/authorized_keys /Users/pair/.ssh/authorized_keys
sudo chown pair:staff /Users/pair/.ssh/authorized_keys
gh-auth remove $1
tmux -S /tmp/pairing new -ds pairing && chgrp staff /tmp/pairing && tmux -S /tmp/pairing attach -t pairing
sudo rm -f /Users/pair/.ssh/authorized_keys

That will download ssh keys, create a tmux session, and attach to it. When you’re done it will cleanup so the other person has no access to your box.

And I have a pair-session script in the /Users/pair/bin directory that looks like this:

/Users/pair/bin/pair-session
1
2
#!/bin/sh
tmux -S /tmp/pairing attach -t pairing

Usage

You can invoke the host one like this: pair-session marksim (replacing marksim with whatever github user you want to pair with)

And your pair simply has to type pair-session to connect.

Requirements

  • github-auth gem (which requires Ruby 1.9)
  • ability to sudo
  • a user called ‘pair’ that has SSH (a.k.a. Remote-Login on OS X) enabled
  • an editor that works in the terminal :)

Positives

  • The user does not have access to your files since they’re not SSHing in as you
  • No need to install a system wide RVM or Ruby 1.9 for github-auth – this copies the .ssh/authorized_keys into your pair account
  • Besides creating a user, you can have a TMUX-ready pair session with a brand new pair ready in under 10 seconds.
  • Automatically de-authorized the user once you’re done.

Negatives

  • I wish it didn’t have to copy authorized_keys – maybe it’s worth hacking to not require github-auth?
  • It requires a sudo password – and can require it twice if your session goes on long enough.
  • Currently, specific to OS X (/Users/, and the ‘staff’ group)

Anyway, I hope it’s useful to others as a simple way to set up your box for pairing.