Closet Coder

I work in my closet. I code. Yep.

Pairing Post Mortem - @_zph - VIM and a Gem

| Comments

Last night I had a great #pairwithme session with @_zph. He’s been doing Ruby on nights and weekends for the last few years and he’s been using VIM much longer than I have. I learned a lot of little tricks about VIM that I just hadn’t quite worked out before. We also refactored some of his Buff Gem.

Setup:

  • Zander had a VPS already provisioned with my ssh keys installed. Super Easy setup.
  • TMUX + VIM for our editors
  • RSpec for testing the Gem

We started off trying to think of what to pair on within Zander’s gem. He was concerned about the tests, so we actually spent a fair amount of time just looking at the WebMocked tests and discussing the pros and cons. Eventually we decided that WebMock might be a good way to start off your TDD of an API wrapper since you have complete control of the response, but VCR gives you the best long term support since you can both get fast tests and confirm that you’re still working with the API correctly and that you didn’t just magically stub out the wrong thing–just delete your cassette and you’ve got “free” real API tests, followed by nice fast tests.

Just having this discussion was valuable. We didn’t change any code since Zander felt it would mostly be tedious and he wanted to do it himself. I can’t decide if that’s a great use of pair time or a ‘wrong’ feeling that some things aren’t worth pairing on. Either way, our time talking about pros and cons of testing styles was one of my favorite moments.

We eventually refactored his url encoding to isolate a few things and make some of the methods query methods rather than query-command mixes. I introduced him to Enumerator#with_index as well. In the process of doing this I saw how proficient Zander was at VIM. He showed me the vim-surround plugin, the vim-numbertoggle plugin, and the vim-ruby-refactoring plugin. I hadn’t really seen any of them in action. I think the refactoring plugin needs to have a bit more to it, but relative numbers really seemed like a great idea. I also learned little things like Shift-j to join the next line to this one and viw to select a whole word. I’d always selected whole lines and yanked whole lines. Learn something new every day.

Takeaways:

  • Discussion is one of the most valuable things about any pairing session. Bouncing ideas off is where you change the way you actually think.
  • Learning tools from other people is just as valuable as improving code.
  • Things I take for granted are easy to forget to point out. I knew about with_index and thought nothing of it. He didn’t know you could chain that off of any enumerator. Ah… the value af other people’s brains.

All in all, a great session. Looking forward to the next one with @_zph.

On to the next pairing session…

Pairing Post Mortem - @Shicholas - Real World Lessons and Bowling

| Comments

Last night I had my first pairing session with @shicholas. Nick recently graduated from law school and is looking to pass the bar, but somehow programming calls to him. It’s a good thing too, since he’s clearly gifted and a fast learner.

Setup:

While we were kicking things off with the “get to know you” talk, I found that Nick had a Rails + Angular.js app he was working on. I’ve not done any work with Angular and asked him to show me what was going on. He pointed out the general structure as well as the custom directives that Angular.js allows you to create. I’ve watched the Ember.js Peepcode Intro, and found it difficult to get excited about it. Being introduced to Angular.js in this particular manner gave me real world applications and it seemed much more intriguing. No verdict yet on either, just initial impressions on both frameworks.

After a few minutes looking at Angular, we decided to implementing the Bowling Scoring as a quick TDD exercise in Ruby. We used shuhari to set up the app and have everything in place for quick exercise. It’s a nifty little gem for speeding up the setup process if you’re wanting to focus on learning something specific.

We got through the whole exercise in about 45 minutes. I’m discovering that Test Driven Development is affected a great deal by the intuitions you have about where something is heading. Implementing the “minimum solution” to pass the test is often subjective. Gary Bernhardt said in one of his Destroy All Software screencasts that there was a point where he could code the constant as a return value to make the test pass, but it was actually much less mental effort to solve it outright, so he did. There was no test that forced him there, he just did it. It made the test pass, and certain other tests didn’t have to be written. We saw this happen in our last 2 tests because of the way we chose to iterate over “frames” in the bowling score implementation.

Takeaways:

  • Be open to learning about what other people are doing. Their real world applications show you much more than any exercise will ever show you.
  • Angular.js looks more exciting than I’d initially thought.
  • shuhari is a cool tool for pairing on basic exercises.
  • Be aware of how much you blur the line between letting tests drive your design and using your intuition to discover the next step.

It was a great session and I am hoping that I get to pair with Nick again on his Angular.js project.

On to the next pairing session…

Pairing Post Mortem - @kmeister2000 - Refactoring and MiniTest

| Comments

Had a great 4th pairing with @kmeister2000. Always a pleasure to work with him.

Interesting Parts of our session setup:

  • Worked on a real world app Karl was developing
  • Used MiniTest instead of RSpec
  • Refactored existing code

MiniTest Takeaways:

  • MiniTest expectations about method calls are not as clear as in Rspec and the documentation/examples aren’t as readily available.
  • MiniTest is a lot like RSpec in nearly every other way.
  • I’m not a fan of Mocha. I think it promotes antipatterns for how to really test.
  • I actually like the explicit mock.verify in MiniTest::Spec

General Takeaways:

  • Real world stuff is hard.
  • Naming is hard.
  • The testing drove us to better design, even if the test wasn’t pretty. We still ended up with a wrapper class for the external Stripe API and converted a before_save callback to a decorator class that delegated appropriately.
  • Being unfamiliar with tools is the biggest time suck when you’re working. High proficiency lets you actually get things done. Low proficiency means you’re learning the tool more than solving the problem.
  • Corrollary: Learn tools on problems you know. Solve problems on tools you know.

Pairing Post Mortem : @hinbody - TicTacToe and TMUX

| Comments

I just finished my first #pairwithme session with @hinbody. It was my first remote session to use TMUX+VIM instead of ScreenHero – I have to say, it was quite easy to use and given the fact that it’s free, fast, and cross-platform, I’ll be using it with any vim users I pair with who are willing. I’d love to get CoVim working since it allows you to use your own vim setup. I drool a little bit at all that. But I digress.

Harley and I got going by deciding to work a bit on our TDD. Harley was interested in improving his understanding of Ruby and how to test better. I’m not the best tester in the world, but pairing is definitely making me better. We went through the Tic Tac Toe exercise I’ve mentioned here before. This time you could see my prior implementations having an influence, but it still went ways I hadn’t seen it go before. I’m convinced that just doing an exercise over and over would give you different results each time, but the pairing aspect of it gives me both drive to complete it and another perspective to consider things I’ve not considered before.

We got fairly far on the exercise–probably the most forward motion I’d seen in the 2 or 3 pair sessions I’d done using it. I was pleased with the results and I’m glad to see the good parts of the implementation solidifying and still see myself being open to other design ideas from people I’m working with.

My biggest takeaway from the session was something Harley said after all was said and done. He said his biggest problem was that he lacked confidence and so he hesitated when answering questions. I think this is the most significant kind of thing we can learn when pairing: how to encourage people who are earlier in timeline than you, and how to be open and unafraid to make mistakes in front of people who are further along as well. Developers are a smart lot, so I think there is often a tendency toward arrogance as a default, but it’s been my experience that most developers know what it’s like to be made fun of. Some respond with humility and patience with others and some respond by trying to put others down to “get back” at those that made fun of them. All I can say is that I’d encourage humility and patience since it will help you in every area of life, including pairing.

On to the next pairing session…

Pairing Post Mortem : @thecommongeek - Ruby Koans

| Comments

I paired with @thecommongeek last night again. This time we were more prepared and I think the session went much better.

In our first session I misjudged where Dennis was as a coder and struggled a bit with how to pair with him effectively. This time we had him drive through ScreenHero and decided to start from the “basics” by doing the RubyKoans.

The RubyKoans are meant for Ruby 1.8.7, but 1.9.3 is commonplace now, so we struggled a bit at the beginning. For anyone going through the RubyKoans on 1.9.3 getting a value19 in nearly all your errors, I’d suggest making the following changes on neo.rb (starting on line 34):

neo.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def __
  if RUBY_VERSION < "1.9"
    value
  else
    :blank_value
  end
end

# Numeric replacement value.
def _n_
  if RUBY_VERSION < "1.9"
    value
  else
    :blank_numeric
  end
end

# Error object replacement value.
def ___
  if RUBY_VERSION < "1.9"
    value
  else
    :blank_object
  end
end

They are not perfect, but they will help you get through the koans as they were intended. It’s a bad idea to put ‘nil’ since some tests end up passing if you do.

After we got past that little problem, it became pretty easy to get rolling. I found that Dennis had the following progression over the course of the hour we worked on this:

  • First handful of koans were just getting used to the output and how to interact with the code
  • For the next few koans, it was just cut and paste, but without the ability to guess what should be in the ‘blank’.
  • The last section of koans we did, Dennis was able to make educated guesses at what went in the ‘blanks’ before running the tests. This was the point that he realized that any mistakes would be pointed out by the tests, but making the guess made him think first.

And so I think he got to exactly where he needed to. The koans are a great exercise for coders that are new to Ruby and they are pretty good for new-ish coders too. They walk you through nearly every aspect of the language.

I really enjoyed this session since I felt like I learned a bit more how to teach in a pairing session. Learning to teach is a huge gift in and of itself! It goes to show you that you can truely learn from pairing with just about anyone, no matter what your respective experience levels are.

On to the next pairing session…

A Commitment to Being Positive

| Comments

It’s really easy to be bogged down with all the crap in life. There is a good amount of it and I don’t know anyone that doesn’t struggle with keeping a good attitude at some time or another. I’ve struggled at various points to stay positive both in my personal life and publicly. I don’t think it’s wrong to have negative thoughts or to even voice struggles or frustrations, but there is a danger in openly venting. It creates a culture that is great at complaining and bad at doing anything about it. It creates an entire set of people bogged down in the crap of their lives, and because of the loud voices they hear all around them, it seems like there is no escape from it. There is so little good that comes from complaining publicly.

So I’m here to make a public commitment to do something about it: I am committing to stay positive.

I have friends and relationships I can confide in. If I need to vent, I know the people that will help me through it. They’re mostly not my twitter buddies or my facebook friends. I want to give those people encouragement and thoughtfulness more than anything. I’m not saying that I’ll be “falsey” here–or perfect. I don’t have to hide my struggles entirely from the public, but I don’t have to openly vent as though that will change anything. I am committing to finding good in situations I’d like to think there’s only bad in. I’m committing to being constructive in any criticism I voice. I’m committing to being a more positive person. I’ll make mistakes and try to learn from them.

It doesn’t come naturally to many people, especially me, but this is a step in the right direction for me (and how it affects my thinking) and the people around me.

Pairing Post Mortem - @javichitone - Improving a Gem

| Comments

I had my first international pairing session with @javichitone tonight. He’s from Peru and will soon be graduating. He should have no trouble finding a job based on the code I got to read of his :)

We talked for a bit and settled into looking at a gem he recently published. Since it was his gem, I elected to drive. I’m familiar enough with gems that I’m comfortable in general, but he knew the specifics of his gem, so to get the most out of it, he needed to be commenting on the specifics he knew and I needed to be diving into figuring out those specifics.

We got his tests running very quickly since he had the gem set up perfectly. A clone and a quick bundle install and we were ready to rake test. I’d never used MiniTest, but it seemed simple enough to switch to after knowing RSpec. All the tests passed, so we were in a position to add features or improve the code.

We did a little of both. The first thing we did was improve performance. One observation about improving performance: there are often no tests to write… you just make sure, functionally, that you’re still passing and then set up a benchmark or direct observation that you’re seeing improved performance results. It wasn’t hard to do a quick cache of the HTTP requests to speed things up significantly. Javier was surprised that you could use an array as key to a hash, but grasped very quickly the “trick” after seeing it.

After that, we decided to improve the API. Javier’s Lyricfy gem lets you easily search a few sites for lyrics of popular songs. The gem scrapes the lyrics off of certain sites and put the lines of lyrics into an array. I wanted to be able to type puts song.body rather than song.body.each {|line| puts line} so we did something sneaky and defined a singleton to_s method on the song.body array and that’s all we needed.

I have never in 5 years of being a Ruby programmer found reason to redefine to_s on an instance of an Array, but tonight it seemed like the perfect use of such a thing. I love how pairing gives me new opportunities to use things I’ve learned, but remained dormant because I don’t ever look at things in a way that lets me use them.

We submitted two pull requests to his gem and called it a night. I’m looking forward to another session with Javier.

On to the next pairing session…

Pairing Post Mortem - @jdar - Chrome Extensions

| Comments

Another great pairing session tonight with @jdar! I continue to be amazed at how pleasant and personable the developers I meet are. The internet is a wonderful place.

First up, I’d never coded a Chrome Extension, so Darius took the reigns and started walking through what we were using. The biggest takeaway I got was to put your pride away when you’re pairing. Everyone’s exploring, we’re all trying to get to the next answer, so it doesn’t matter if we’re really well prepared or never coded before… just take the next step.

And we did. We started down the path of trying to get a Chrome extension installed and running locally. It was easy enough to do. We started off by forking Firebase and then using Chrome Extensions “Load unpacked…” option. Worked like a charm and we were off.

The next step was to try to write some Jasmine tests. After realising that we were struggling with both the testing framework, the Chrome Extension framework, and the intereactions of the collaborative editor we were working with, we decided to go toward a code spike to “get things working” – sometimes this is what you need to get a sense that you’re exploring and making progress. Pairing is good for this since it makes you less likely to spin your wheels for a while. There were multiple times that Darius remembered things I had no clue about and a few times I helped him out. +1 for Pairing.

After that we got our basic extension code running in the right context and wrote out to the console. Doing this drove us forward to start doing what we expected, which is see our collaborative editor inside the github page.

We ended our session by seeing an error in our console so we would have a great jumping off point next time.

I loved this session for a few reasons. It’s the first session I didn’t drive much on, so I spent most of my time learning. I also enjoyed the idea of learning a new technology by pairing. So many times I try to set up time to learn something new and I end up playing Angry Birds instead. This allowed me to focus on learning a bit. Now I have a very basic understanding of something I had no clue about 3 hours ago. What a great investment.

On to the next pairing session…

Tricks and Tips I've Learned for Coordinating Pairing Sessions

| Comments

When I heard about the #pairwithme idea, I thought it was something I really wanted to do. I set aside 3 nights a week from 9-10pm and started pinging people on Twitter during that time, asking if they wanted to pair. I tried for no less than 3 weeks before actually getting a real pairing session going. I had several cancellations and a bunch of fits and starts trying to figure out how to really communicate with people. Here’s my takeaways from the experience of coordinating sessions remotely.

  • Get off of Twitter as quickly as you can. Go to direct messaging, then get e-mail or some kind of chat to ‘formalize’ the relationship a bit
  • Use a Calendar and actually send the invite. It virtually guarantees that you’ll be on their calendar and helps both of you remember.
  • Pre-agree on where you’ll meet. Google Plus seems to be the most common, though I’ve seen some people get into IRC. Either way, include it in your calendar reminder.
  • You need about 1.5 - 2 hours to do a good session. It takes at least 10 minutes to ramp up and if you’re meeting someone for the first time, it can go as long as 30.
  • Double book (with people’s full knowledge) if you can. I.e. “If my 8:00pm session cancels, I’ll ping you and see if you’re available… cool?”

All in all, I’ve found it difficult to get started, but now I’m booked out for 3 weeks. We’ll see how they go. :)

Pairing Post Mortem - @kmeister2000 - TDD and Domain Knowledge

| Comments

Last night I did a #pairwithme session with Karl Meisterheim. He’s an experienced developer who currently work part time and was looking to improve his skills. Besides having a good deal in common and really enjoying our conversation, I also learned a bit more about remote pairing and came away with a couple of observations.

First off, we paired 2 nights in a row for about an hour each night. Both sessions we tried to solve the same problem: TicTacToe. We started off on the second night with the code from the first night, but quickly threw it away and decided to “start over” as an excercise. Doing this taught me the most significant lessons from our session.

The code from the first night ended up heading in a direction we didn’t really like. It wasn’t horrible, but it wasn’t something we felt confident in. I learned about Sublime’s Vintage mode (a very nice way to pair with someone where one is used to VIM and one is used to TextMate/Sublime!) and I experienced ScreenHero from the client side. I still have the same observations about it as I did at my other pairing session: great product for a super fast, no fuss setup.

So the second night, we threw the code away and started again. Doing that gave us the lessons we learned from the other code without being tied to our former implementation. We went in a completely different direction, summed up nicely in an observation Karl made: “TDD is no substitue for lack of domain knowledge.” When we struggled the night before, it was mostly because we didn’t have a clear idea of what we wanted to implement. Taking just a few minutes and writing down comments that described the properties of a TicTacToe game made a great deal of difference. This has been referred to more ‘formally’ as README driven development. Write your README first and make your specs off of that… then your code off your specs.

As programmers, we are often translators between English (or your native tongue) and ‘Computerese’ (in whatever flavor you subscribe). Taking the time to make small steps between the words you speak and the code you write is part of being a good developer.

All in all, a great experience with Mr. Meisterheim! Hope to do it again on a more ‘real-world’ problem next time.