Resident Demigod

Veezus Kreist

Divine missives

A retrospective: My time at Hashrocket

July 21, 2011 16:36

TL;DR: My time at Hashrocket is coming to an end. It's a very bittersweet experience, leaving this company that has come to define me over the last several years, but it is become the season for change and I'm ready for my next challenge. Ping me if you're looking for a consultant experienced in ruby and rails.

I have a tattoo of Hashrocket's logo on my right calf. It's an odd thing, people say, to have a corporate logo on one's body. But for me, it's completely natural. When I'm in the presence of conversations regarding ruby 1.9's new hash syntax or my upcoming departure from Hashrocket, I inevitably get asked: "What about that tattoo on your leg?"

At first I was confused by the question. It took me a while to get to the source of the confusion: folks seem to have a base assumption that regret follows when the meaning of a life-altering body modification changes. I have only this one tattoo on my body, and it comemmorates what is thus far the single most awesome experience I've had. Regardless of what happens from here on out, I will treasure and honor the myriad experiences I've had as part of Hashrocket. I've earned the right to wear that tattoo, and I'm honored to give those square inches of skin on my leg to help keep those experiences alive in my memory.

In my time at Hashrocket, I've had the great fortune to work alongside some of the best developers in our field - in a company whose original members included the likes of Obie Fernandez, Desi McAdam, Jon Larkowski and my brother Jim Remsik. I've learned more about consulting and client relations than I ever dreamed I would. And I've learned a ton about what Agile means, and how to stay flexible among changing team and client dynamics. A friend pointed out recently that I've been at Hashrocket almost as long as one attends university; this observation feels especially apt given the amount that I've learned and grown.

The memories of my time at Hashrocket will last a lifetime: a year in Hashrocket time feels like 5 anywhere else. I'll remember our "garage", where we first came together as a company. I'll remember the RV trip to the Ruby Hoedown, getting our new digs in the tallest building in Jacksonville Beach, the Hashrocket Hot Hackers Hump-day Happy Hours, the pool parties, the 3-2-1 launches, the rescue missions seemingly uncountable, the Halloween parties and that birthday where Mark sat in his cake, and of course the video that tpope gifted us commemorating three years of Hashrocket.

There's been almost as many downs as there have been ups: I know I'd certainly like to forget 2010 and all of it's troubles. We had multiple robberies (which were solved, thanks to anti-theft tech on our machines), we had some management shakeups, and even several situations that could have meant the end of the rocket. But we celebrated New Years 2011 as a company: we made it through the crucible as a whole, finding ourselves in an an awesome position throughout 2011.

I was given an opportunity a little over a year ago to come work at the Chicago office, shortly after it opened, and I jumped on it. It took some time, but it's blossomed into an exceptional office. I'll remember fondly, too, memories from up here: post-6H karaoke, the Josh, Yoho, and Bernerd eras, the ever-present and always-welcome Corey Haines, the grand opening party for which we "needed" that 55" plasma TV, the company game of Whirlyball featuring David Chelimsky and Neal Sales-Griffin, the apartment debachles, being the lonely sole rocketeer in the city, and two Tuesdays ago when we were a party of nine at Six Flags Great America.

It's a bittersweet time for me, these last two weeks of my employment with Hashrocket. There's a pride in knowing that I helped make our office what it is, and a sadness knowing that it will go on just fine without me. But you can bet I'll be back in the office visiting whenever the chance arises!

So, what's next? I'm not yet sure. I'd like to work on a product for a while, or at least cool my heels from the continual churn of consulting. I'd like to work with a group of awesome everyone-together developers that value continual learning and the occasional code-based flame war. And I'd like to use the knowledge I've gained during my time at Hashrocket to help another team achieve success. Know a place like that? Email me at almighty@veez.us.

Ignoring machine-specific changes to .rvmrc

August 11, 2010 15:43

At Hashrocket, we use RVM to manage our rubies and gemsets on client projects. We typically specify the version of ruby that’s in production in our .rvmrc, like so:

rvm_gemset_create_on_use_flag=1
rvm 1.8.7-p249@vurl

However, sometimes a machine will have a problem with an installation of ruby, and so we’ll use a different version on that machine. Yeah, the correct solution is to fix the damn ruby, but we solved the problem today by flexing some little-used git fu… updating the index to ignore local changes to a file.

So, our `git status` shows us:

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   .rvmrc
#
no changes added to commit (use "git add" and/or "git commit -a")

Now let’s instruct git to assume our .rvmrc is unchanged:

git update-index --assume-unchanged .rvmrc

And now our `git status` looks much better:

# On branch master
nothing to commit (working directory clean)

Repeating the previous command in bash

July 23, 2010 15:38

As a developer, I’m always looking for ways to keep my hands on the home row when typing. One of the few times I still use the arrow keys on my keyboard is when I want to repeat the previous command in bash. The solution? Use ctrl+p to cycle through previous commands, and ctrl+n to move forward through them.

Thanks, Bernerd!

On Chicagoan Tornado Sirens

July 03, 2010 13:21

It was a Wednesday a couple weeks ago. We were a group of Rocketeers on a wind- and rainswept balcony overlooking the river in downtown Chicago. All of the business types had fled after a table overturned in the maelstrom, but we were Hashrocket, and this was our happy hour. The waitress was thrilled that we continued to order drinks.

And then something strange happened… a siren started to sound. I had never heard anything like it, and my initial impression was that there was a normal police siren sounding that was being distorted by the buildings and rain.

Turns out, it was a tornado siren. But hey, it’s going to take more than a little tornado to keep us from our happy hour. Here’s the audio of the event:

Error: OpenSSL when installing ruby 1.8.6 with rvm

May 11, 2010 13:22

We’re hosting a project on EngineYard and, unfortunately, they currently only support ruby 1.8.6 patchlevel 287. When trying to install ruby-1.8.6-p287 with rvm, however, make generates the following error:

In file included from openssl_missing.c:22:
openssl_missing.h:123: error: conflicting types for ‘BN_rand_range’
/usr/include/openssl/bn.h:411: error: previous declaration of ‘BN_rand_range’ was here
openssl_missing.h:124: error: conflicting types for ‘BN_pseudo_rand_range’
/usr/include/openssl/bn.h:412: error: previous declaration of ‘BN_pseudo_rand_range’ was here
make[1]: *** [openssl_missing.o] Error 1
make: *** [all] Error 1

The solution involves installing a custom OpenSSL package with rvm. You can get details directions directly from the source: http://rvm.beginrescueend.com/packages/openssl/

Faking a multipart form upload with webrat

April 05, 2010 20:29

We’re developing an API of sorts for one of our clients. We’ve got an API that expects some form data for an Item and an optional file sent along. We ran into a little bit of trouble sending this file along with the request. We took a cue from the way webrat submits its forms for our solution:

file = File.open("path/to/fixtured/file")

params = { :item => {:new_file => ActionController::TestUploadedFile.new(file.path)} }

visit api_item_path(item), :put, params

Returning multiple IDs when using finder_sql

March 22, 2010 20:54

We ran into some trouble today with finder_sql. Our object graph is fairly complicated, and can be summed up like this:

Job has many
Items, which have many
Processes, which have many
Cycles, which are iterations of many
Tasks.

This leads to us doing some pretty crazy SQL to compress the graph and save on database hits, and led today to an interesting discovery. We had done a has_many on User to return a list of tasks the user was able to perform. The finder_sql we generated looked like this:


SELECT *
FROM tasks t
INNER JOIN cycles c on t.cycle_id == c.id
...
INNER JOIN jobs j ON i.job_id = j.id

Unfortunately, the fist ID returned belonged to Job, so while the attributes for each Task was correct, the ID was actually the Job’s ID.

The fix was to select only the attributes of tasks:


SELECT t.*
FROM tasks t
INNER JOIN cycles c on t.cycle_id == c.id
...
INNER JOIN jobs j ON i.job_id = j.id

Writing a Builder::XmlMarkup to file

March 18, 2010 20:56

Matt Yoho and I have been working on interfacing with a SOAP-based external service with no documentation and hosted on Windows. During the course of feeding this service XML to try to get it to react as we’d like, we realized we didn’t know how to write out a Builder::XmlMarkup object to file without adding a new to_s element.

The solution? Calling target! on your object will return the string that Builder is building.

tempfile.write xml.target!

Specifying an older rubygems version with RVM (updated)

March 16, 2010 17:15

Updated with user-based configuration – thanks, Wayne

I’ve recently been in the uncomfortable position of trying to work on rspec-rails (which requires rubygems 1.3.6) and a legacy app that Hashrocket has been maintaining (which works with 1.3.5 or earlier). I’d been hearing about RVM and decided to give that a whirl.

However, by default, RVM was installing rubygems 1.3.6. After a little bit of struggling, I found the place to change the default rubygems version to install. In ~/.rvm/config/user, add the following line:

rubygems_version=1.3.5

This will override the default setting in ~/.rvm/config/db. Install a new ruby and check your gem version:

rvm install 1.8.7-p174

rvm gem -v

Prune your remotes

September 12, 2009 04:31

Lark and I were working on a project the other day and were nowhere near a commit at the end of the day. So we created a feature branch and pushed a WIP commit:

1
2
3
4
5
6
veez ~/code/some_app (master)$ git co -b client_edits_business
M        app/models/user.rb
M        spec/models/user_spec.rb
...
Switched to a new branch 'client_edits_business'
veez ~/code/some_app (client_edits_business)$ 

We finished up the feature the next day, and a week or so later Lark IMed me asking if there was anything on the branch that needed saving. I knew there wasn’t, so I deleted the remote branch:

1
2
3
4
5
6
7
8
9
10
11
veez ~/code/some_app (master)$ git branch -a
  client_edits_business
* master
  remotes/origin/client_edits_business
  remotes/origin/master
veez ~/code/some_app (master)$ git branch -d client_edits_business
Deleted branch client_edits_business (was 1fc95e5).
veez ~/code/some_app (master)$ git push origin :client_edits_business
To git@github.com:hashrocket/some_app.git
 - [deleted]         client_edits_business
veez ~/code/some_app (master)$ 

The next morning Lark asked me about the branch again, as it was still showing up in his tracked branches:

1
2
3
4
jon@mbp2:~/git_hashrocket/some_app$ git branch -a
* master
  remotes/origin/client_edits_business
  remotes/origin/master

The solution? Prune your remote:

1
2
3
4
jon@mbp2:~/git_hashrocket/some_app$ git remote prune origin
Pruning origin
URL: git@github.com:hashrocket/some_app.git
* [pruned] origin/client_edits_business

Integration testing without cucumber

September 12, 2009 02:38

There are three main testing cliques at Hashrocket: the Fakirs, the Derivatives, and Team Zombie. Fakirs are so named because they stub and mock everything – making it all fake. Derivatives are the exact opposite, preferring to forego unit testing in most cases and just write integration tests that interact with the code through a browser. Team Zombie (the “decomposers”) had just the right mix for me: integration testing for core business value, unit testing individual methods, and stubbing them elsewhere. Personally, such a technique helped me with my data models: too many stubs means too complex a model.

Additionally, I’ve never been in love with cucumber; the regexes drive me crazy, and I’ve never had a client who wants the (admittedly very nice) story formatting that it gives. I’ve been working on a green-field app this week at Hashrocket for the first time in months and it’s given me an opportunity to try out a new integration testing methodology and has called into serious question my membership in Team Zombie. Tip of the hat to Sandro for turning me and Voxdolo on to this technique.

Here’s a quick and dirty implementation of integration testing with rspec and webrat on Vurl (source), using the techniques I picked up this week.

Configure your application

In config/environment.rb:

1
2
config.gem 'rspec-rails', :lib => false, :version => '1.2.7.1'
config.gem "webrat", :version => "0.5.3", :lib => false

In spec/spec_helper.rb:

1
2
3
4
5
6
7
8
9
10
11
require 'webrat'

Webrat.configure do |config|
    config.mode = :rails
end

Spec::Runner.configure do |config|
  ...
  config.include(Webrat::Matchers, :type => [:integration])
  ...
end

Create your spec

1
mkdir spec/integration

Here’s my spec/integration/create_vurl_spec.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))

describe "Create Vurls" do
  it "redirects to the vurl show page" do
    submit_vurl 'http://google.com'
    current_url.should == vurl_url(Vurl.last)
  end 
  it "shows a success message" do
    submit_vurl 'http://google.com'
    response.body.should include('Vurl was successfully created')
  end 
  it "creates a vurl" do
    submit_vurl 'http://veez.us'
    Vurl.last.url.should == 'http://veez.us'
  end 
end

def submit_vurl url 
  visit root_path
  fill_in "vurl_url", :with => url 
  click_button 'Vurlify!'
end

Run your spec

Since your spec file ends in _spec.rb, it will run with the rest of your spec files. Just give your app a

1
rake spec

A note about rspec matchers

When running these rspec tests, we don’t have access to the rspec matchers. So things like

1
flash[:error].should_not be_nil

won’t work because the be_nil matcher isn’t loaded. You can always fall back to Test::Unit:

1
assert_not_nil flash[:error]

Or, better yet, test that your content is within the body:

1
response.body.should include('There was a problem creating your vurl')

This method of integration testing feels much lighter to me; the tests take less time than cucumber equivalents and we’re not writing and maintaining a separate set of regexes to go with the app.

Enki blogging app

September 07, 2009 20:34

I’ve been going through a rebranding effort lately, moving away from Matt Remsik or Veez to Veezus Kreist. I believe Veezus will be a stronger brand that will result in less name collisions with other folks on the internet.

Part of this effort was moving my blog from Blogspot to something I’ll host myself at blog.veez.us. I considered many solutions: Mephisto, Simplelog, and Enki

Mephisto was active but seemed large and bloated with features I wouldn’t use (and the Documentation tab kept throwing 404s). Simplelog was no longer being maintained. Enki was just right, providing a simple blog application with everything I needed.

I was able to get my enki blog up and running, with all posts and comments copied over, in about two hours. I’d recommend it for a personal blog that doesn’t need features like multiple authors and that you want to easily modify.

The Virtues of VirtualBox

September 07, 2009 16:33

Development Platform. As a newly-minted Ruby on Rails freelance developer, the first thing I wanted to do was find a development platform that wasn't Windows. Not that I have anything against Windows (indeed, I've taken Microsoft's side in many an argument), but lesser support for development tools and command line differences between the two platforms meant that I'd have a lot easier time using either Mac or Linux.

Macs cost alot; Linux distributions are free. That pretty much decided me in favor of Linux. The best Rails editor is available only for the Mac platform, but one editor wasn't about to compel me to pay for a Mac.

The next decision I had to make was whether to abandon Windows. I didn't want to lose the games I play, and I didn't want to spend the time rebuilding my current PC just to take advantage of the development benefits of using Linux, so I decided to try out a virtual machine.

Microsoft VirtualPC. Being accustomed to using Microsoft's development products over the last seven years, the first virtual machine application I tried was Microsoft's VirtualPC 2007. I was able to find some great posts with instructions on getting Ubuntu to work with VirtualPC and, after a couple of days, I had set up an Ubuntu system.

I used VirtualPC for almost a week; ultimately, there were two issues that prevented me from accepting Microsoft's product for the long haul. The first was the scroll wheel on my mouse: VirtualPC didn't support it. At all. This was apparently a decision they made to maximize compatibility with older operating systems, but, whiny as it sounds, having to click the scroll bar every time I wanted to move a window was a no-go. The second issue was sound: I just couldn't get it to work.

VMWare Workstation. The next product I tried was an offering from VMWare for a thirty-day trial of their Workstation product. I only spent about thirty minutes trying to get this software to work; the cost to purchase a license led me to decide if I couldn't get it up and running in a drop-dead simple way, it wasn't worth my money.

Innotek VirtualBox. The final product I tried was Innotek's VirtualBox. I was pretty annoyed by this time; wasted time and several failures had pretty much soured me to virtualization technologies. While browsing an old and crappy forum (so old and crappy, in fact, that I can't find it any longer), I found a reference to a product called VirtualBox. Figuring I had nothing to lose, I downloaded a copy of the software, installed it, and booted up a new virtual machine.

I was blown away. No hacks were required to get Ubuntu to install. The sound worked, the networking worked, even the scroll wheel worked right out of the box. In less than an hour I had a fully-working Ubuntu system at my fingertips. For free.

VirtualBox installs on Mac, Linux, and Windows systems. And it will run virtual instances of those operating systems on any of the others. It'll even let you set up shared folders between the two operating systems for easy transfer of files.

If you're going to use a virtual machine, I strongly recommend VirtualBox. It's by far the easiest virtualization software I've found, and it's free for most people.

My associated records based on time are caching!

September 07, 2009 16:32

I had been working for the last few weeks on a tricky issue. Given the following code:

class Vendor < ActiveRecord::Base@
  has_many :vlogs, :conditions => ["vlogs.published_at < '#{Time.now.to_s(:db)}'", ]
end

The items listed for each vendor would cache an arbitrary amount of time after the server was started. Restarting mongrel would resolve the issue – until Time was cached again. I spent more hours than I care to think about trying to resolve this issue with various Hashrocket and EngineYard staff. The only solution presented was:

class Vendor < ActiveRecord::Base
  has_many :vlogs, :conditions => ["vlogs.published_at < ?", Time.now.to_s(:db)]
end

Which didn’t work, anyhow. I finally spent some time with Tim Pope this evening, and he provided the following, correct solution:

class Vendor < ActiveRecord::Base
  has_many :vlogs, :conditions => ["vlogs.published_at < '\#{Time.now.to_s(:db)}'", ]
end

The trick here is that Ruby is interpolating the date string; ActiveRecord never even sees the reference to Time.now. Apparently, deep within ActiveRecord, there’s a regexp that searches for string to interpolate. The solution, escaping the pound symbol, allows ActiveRecord to find and execute the interpolation.

Pairing as a way of life

September 07, 2009 16:30

Hashrocket has a few core philosphies that are essentially required for team members. Agile development processes, an adherence to ruby and rails best practices and idioms, and a firm belief in pair programming are three of the biggies. Of these three, pair programming is the technique that has changed me most, and required the most change in my thinking. And not surprisingly, pair programming has proven the most critical to my success at Hashrocket.

I knew of pair programming before I came down to check out the Hashrocket way. And I even knew some people who personally advocated pairing. But I was that guy. You know, the one who does his best work in the morning with his headphones on and drinking an obscenely large coffee. The guy who types madly for a few select hours a day and, during those few hours, produces as much as regular-speed developers do over the course of a day.

There was definitely a transition period when I would only have a pair for half a day here and there where I was still that guy even though I was with Hashrocket. But ultimately, I have come to realize three distinct situations in which pairing is far superior to working solo that have cemented my belief that pair programming is superior to solo programming.

First, a big part of coding is constantly seeing the big picture. I can't tell you how many times I've sat down to solve a problem and been blind-sided by a particularly difficult routine to write, or maybe a supremely complex data model. Or maybe I find that I have to monkey-patch some existing code. These situations inevitably make me sit and spin my wheels for a minute... sometimes they even made me get up out of my desk and waste some time thinking about solutions. Occasionally I would give up and leave early for the day. With a pair sitting next to me, however, a simple discussion of the situation typically leads to a more obvious solution. In worst case scenarios, we are still more productive by keeping different parts of the solution in each of our heads.

Other times, that obscenely large coffee is just a bit too much and I get going a little too fast. I make simple typos or logic mistakes that I don't catch until I've already started running tests, and then I end up wasting 30 seconds waiting for tests to tell me that I've entered a period instead of a comma. As an over-caffeinated developer, I can't tell you how frustrating these little typos and large amounts of wasted time become. With a pair by my side, it's very rare thing that I get to the end of any line of code without one of us noticing a typo.

The last situation that I've noticed an improvement in development speed while with a pair is after lunch. I don't know about anyone else, but I get very yawny after lunch. So instead of spinning my gears alone and staring off into space, my pair and I typically find myself getting into more code discussions, or letting my pair drive while I keep an eye out for typos. Either way, I'm way more productive than I would be while browsing digg.com.

For all of these reasons, I've become a huge believer in pair programming. And since becoming a believer in pairing, I've found myself extending the idea of pairing to other areas of my life: I pair at the gym with my gym buddy, I have a haircut buddy, and I typically line up my schedules for things like DMV runs with other folks.

But the real reason I wanted to talk about pairing today was my latest pair adventure: presenting. I'll be honest; I think I'm a terrible presenter. There was a time in High School when I won awards for giving speeches. That was almost a decade ago, though, and I'm a little more than frightened about getting in front of a large group of people.

Being at Hashrocket, it's no surprise that I'm surrounded by people way smarter than me. In this situation, having a more senior pair is quite possibly the best thing I could have asked for in my career. And also, being part of a brain trust such as we are, it's only natural that all of us Rocketeers should be presenting at a few conferences a year. And let me tell you, I'm not the only Rocketeer terrified of getting up in front of a crowd.

So my solution: present two topics at once in a stream-lined talk about two different topics. Jax CodeCamp is coming up, and I'm hoping to present a talk discussing distributed development with git and rapid web application development with rails. As a side effect we'll also be discussing pair programming, but that should be in a mostly meta sense. The idea is for one of us to create an application and commit it to a git repo and from then on to ping-pong back and forth, making incremental application improvments and highlighting the uses of git in distributed development while we do so.

The benefits of doing so should be two-fold: first, to show how awesome ruby on rails and git can be, and second to decrease the likelihood that either me or the other speaker will run out of the room screaming.

Wish me luck?

On presenting

September 07, 2009 16:29

In high school I was well-known for public speaking. I took a speech class my sophomore year in which we did nothing but present speeches. We held three contests that year, and I took first place in all three contests. That was a dozen or so years ago, though, and I haven't spoken in front of anyone for at least a decade.

As a member of Hashrocket, I've continually been espousing the view that, as leaders in our field, we should be constantly presenting. How can anyone in the field take us seriously if we don't show up in force at conferences, have well-attended talks, and share as much knowledge as possible? Well, this last weekend I had the opportunity to eat my own words and speak at Jax Code Camp, a mostly .Net conference that is looking for some diversity. My co-worker, Rein Henrichs, did me a solid and stepped in for my missing scheduled pair.

In so doing I was able to re-live some rookie mistakes in presenting. Luckily, I also remembered a few skills that saved my ass.

First lesson: keep a local copy of your slides. I didn't have a lot of slides, but the purpose of them was to keep the audience looking at something other than me and to provide the occasional comic relief. I got to the conference and was able to view my Google Docs slides just fine; it was only after I had to switch rooms due to projector issues that I realized my new location didn't have internet access, thus leaving me slide-less in front of a large group of strangers.

My saving grace in this situation? I had created a card with important talking points for each slide I had created. I created a short hand in high school that allowed me to keep key sentence fragments in my head and remember the surrounding sentences easily. With 10 minutes of slides suddenly gone, those cards were the only thing that saved me.

Second lesson: you're going to panic anyway. I spent somewhere between 12 and 16 hours preparing for 20 minutes of talking and 30 minutes of live coding. What did that preparation ultimately net me? 20 minutes of panicking at the beginning of the talk. My hands shook, my voice was querulous, and my eyes darted around frantically without meeting anyone's eyes.

My saving grace in this situation? My cards, again. So long as I was able to focus on putting one word in front of another, I was somehow able to keep from running out of the room screaming. I also asked the group to laugh at me right away, which may or may not have helped settle me down.

Third lesson: bring water! Two very kind souls gave me water during my talk; without them things would have been even rougher (even though I did manage to choke on said water halfway through the talk). The more nervous you get and the more you need to talk, the more crucial water becomes.

The real takeaway from this weekend's code camp wasn't that it was a series of failures; rather it was that despite a series of failures, a success was achieved. Rein Henrichs and I presented the topic together. We ran over the alotted time. We engrossed many people; our talk was standing room only. We extended the Hashrocket brand. We probably convinced some people to use git in their daily development, and we may have even convinced a couple to check out Ruby on Rails.

Now that my decade-long presenting cherry has been broken, look for much more from me.

On my first tattoo

September 07, 2009 16:23


Some people have asked why I’ve got a Hashrocket tattoo on my calf. The reasons are pretty biographical; ‘ware ye the history contained herein. Credit for the photo goes to Travis Schmeisser.



Each Wednesday Hashrocket has a midweek get-together called Hashrocket Hot Hackers Hump Day Happy Hour (or 6H). It was a chilly January evening and there were almost a dozen rocketeers milling about at the local martini bar when Sal casually asked if I wanted to go get a Hashrocket tattoo with him.

Of course, inebriated as I was, there wasn’t much chance I was going to turn down the idea of getting a Hashrocket tattoo.

Yet, there was a time when I considered tattoos silly things that a person gets to show how edgy he or she is, or to indicate an extreme level of I-will-kick-your-ass. Now I’ve got one. So why choose to get a Hashrocket tattoo?

I’ve become quite enamored of Hashrocket since I arrived in Atlantic Beach at the end of March in 2008. I was still a recovering burn-out when I came down here, and somehow Hashrocket refilled my spiritual-coding cup. That sounds extreme, but it’s just the way things are.

I spent five years at a county-level government IT shop as a web programmer. I serviced sixteen department websites and also wrote an intranet from the ground up that served 1700 employees while I was there. My boss was lost on anything past FrontPage and for help I had only a string of limited-engagement, part-time assistants of varying levels of skill.

I burned out. Totally and completely. I threw away all of my computer gear and went back to auditing hotels overnight and contemplatively staring at the moon. After about a year, I had the realization that software is what I do, and no matter how burned I felt or how much I wished otherwise, it seemed that was the value I would provide to society.

I began the slow road back to development by working as a part-time webmaster at a non-profit. Then Tiger turned me on to Ruby on Rails, and things started to happen inside of me. A strange sensation that, after experiencing a few times I was able to place: happiness. I was happy writing ruby code. I was happy using the rails framework. Just typing out each line of code somehow made me feel good.

That’s how I came to be a Rails consultant in Madison, Wisconsin. My first paid site was completed in November, 2007, and I’ve never looked back.

When Tiger invited me to come down and see how Hashrocket does things in March of 2008, I was excited to see the magic sauce that had both he and Lark raving about the company. I didn’t expect to be offered a job, but I was, and it’s been the best thing that’s happened to me.

In many of the same ways that ruby and rails took away the pain of coding for me, Hashrocket has taken away the pain of work and replaced it with happiness. Pair programming has made me a more effective and efficient programmer. Communicating all the time has taken away all the bad conversations, because nothing has time to fester. Test-driven development gives me a level of confidence in my code that makes me unafraid to change even systems I haven’t looked at in ages. I feel encouraged to excel as an individual rockstar within the community, even on the Hashrocket clock. As Les Hill (in the photo, on the right) is wont to remind us in his blog posts, working at Hashrocket is like attending an ongoing seminar.

All of these reasons, from my discovery of Ruby on Rails through joining Hashrocket and even becoming a presenter at local user groups, this is why I have a Hashrocket tattoo on my calf. If I never have another experience that I want to commemorate with a tattoo, I’m glad I’ve had this one.

On vim targets

September 07, 2009 16:22

It must be noted that my first experience at Hashrocket with vim was a few weeks pairing with Tim Pope (the dude who wrote the rails.vim plugin you should be using) on a rescue mission. I didn’t touch the keyboard for three days – that’s how many hours of watching the man operate it took me to absorb the ridiculously awesome things he was doing. Credit for nearly all of my vim knowledge goes to him. The rest goes to the other Rocketeers who put up with my continual discussions about how to more quickly achieve line edits.



I thought I might sit down and document some key ways that I interact with vim, and then I realized that would take a couple hours and way more thought than I want to put into a drunken Saturday night. So I decided to talk only about targets instead.

In vim are the concepts of actions and targets. Actions are pretty straightforward and are really only useful when combined with targets. Some actions in vim are listed below for reference.
  • d: delete
  • y: yank (copy)
  • c: change
  • v: select
Targets in vim are one or two character combinations. I’ve listed some of the most common targets I use below.
  • iw: in word
  • t: to the character before the next character entered
  • f: to the next character entered
  • $: to end of line
Combining actions and targets results in some interesting scenarios:
  • ciw: change in word. Whatever the word under the cursor, remove it entirely and put me in insert mode.
  • diw: delete in word. Delete the entire word currently under the cursor.
  • ct.: change to the next period. Helpful for changing the name of an object, but not the method called on it.
  • ct(: change to the next open paren. Helpful for changing the name of a method.
  • df): delete to next close paren. Helpful for deleting entire method calls.
  • yiw: yank in word. Yank the entire word under the cursor.
  • d$ or D: delete to end of line
  • c$ or C: change to end of line
  • y$: yank to end of line
Do you use vim? Why or why not? If you do, what interesting ways do you use vim’s targets?

On local radio stations

September 07, 2009 16:21

Today I got followed by @chumley1073, and employee of a local new rock station called Planet Radio (107.3 FM in Jacksonville, Florida).

You see, until recently if you wanted to listen to any new rock in jax, you had to listen to Planet. What changed that fact was the arrival of X 102.9. What was previously an 80s pop station suddenly became the one thing I never expected: a competitor to Planet.

I'm not a very big fan of Planet; the reasons seem like they should go in an unordered list:
  • Lex & Terry, morning shock-jocks and relationship advisors, prevent me from rocking out in the morning
  • The music played was new rock, but it wasn't exactly what I wanted to hear. I like to hear songs that are more frenetic than heavy.
  • Commercials. Planet played a lot of commercials.
X 102.9 was all of the things Planet wasn't, and it was good. I immediately changed my number one slot to X 102.9. I think it was three days before I heard a commercial. That's likely because they didn't have any advertisers, but I still rarely hear commercials. And then they started playing snarky ads comparing the number of commercials on each station in the last hour, and about Lex & Terry being old, bald men.

Shortly thereafter, I heard their request line announcement. In order to request a song, you must text the song title to them. They apparently don't have a phone line. And then they announced their twitter username (@x1029jax)... followed by their facebook page. Last week they announced a contest you could win by becoming friends on Facebook, and today they asked listeners to friend them on twitter.

All of it makes me think of some random dude sitting in a window-less concrete-walled room recording sound bytes and checking texts, facebook, and twitter... just the type of super-lean operation that can build off of larger Planet's existing ad network. Sure you could advertise on Planet, but why not use those ads they helped you develop on our station for much less?

You can see Planet reacting already to the existence of X 102.9. I heard a kick-ass song, "Sex on Fire" by Kings of Leon, on X 102.9. About a week later I heard it on Planet. It's not the type of music I expect to hear from them. Planet has shot back at X 102.9 with an ad that suggests a puppy dies each time a listener switches to another radio station. And now, an employee of Planet has followed me on twitter. I didn't follow him back; it feels like Planet is just trying to play catch-up.

All in all, it's an interesting play that X 102.9 has made, and I'll be listening to see how it all turns out.

On localpolitics.in

September 07, 2009 16:19


Being the social progressives that we are at Hashrocket, we were excited when Obama announced the Martin Luther King Jr Day of Service. Then, when we found out that Sunlight Labs was holding a contest called Apps for America, it was quickly decided that we’d honor the Day of Service and have a hack day to create an app. With a design from local firm Thought & Theory, a number of local tech folks joined us in the orbiting Hashrocket HQ to lay the foundations for localpolitics.in.

Over the course of the next two months, many small tweaks and enhancements were made and a second hack day was held. The final result was submitted to Sunlight Labs on the day of the deadline. On Sunday, we were notified that we had taken an honorable mention for our efforts. All of the sites created were well thought out and executed; I was really excited to see the quality of the work done by other contestants.

Thanks to everyone who helped work on the project. They are: