I Will

As of about a month ago, I am officially in the business of house protection.

That’s a really terrible joke way of saying I’ve joined Under Armour Connected Fitness to work on the API team. I’m really excited about the team’s mandate from the company and where the Connected Fitness division is going, in general.

In my previous post, I outlined some things I was looking for in a new job. As a refresher: Ruby, social justice, APIs, hypermedia, service oriented architectures, practical design, not moving away from Austin. UACF hits all of those except the first two, and it hits them hard.

The UACF Platform is a HAL(ish) API, so the company has been doing hypermedia in one way or another for a while, now. And I think there’s high-level buy-in about the benefits hypermedia can bring to a public API like ours. In a similar vein, there’s serious work being done on the SOA-front across the company. Having the technical leadership interested in going where I want to go and in using the tools that I want to use is great.

One thing I’ve been particularly delighted to see in practice and talk about with my new teammates, is how Under Armour’s dedication to quality and doing sound engineering transfers to the world of software. The philosophies that govern how the company has thought about building their physical products dovetails very nicely with my thinking about what good software engineering is and what I’ve described as practical design. Specifically, the API team isn’t tasked with making a platform so we can check off a box; we’re being asked to make a best-in-class API. My personal goal for the team is to make an API that other companies envy and want to emulate in every facet, from documentation to performance and I feel like we’ve got the backing from the top to make that happen.

As for not moving away from Austin, UACF just moved into new offices in Austin’s old Seaholm Power Plant. While the space is amazing, the bigger deal, to me, is that Austin is Under Armour’s Connected Fitness HQ. It is obvious to me that Under Armour is seriously invested in the Austin office and team.

I won’t, however, probably be using much Ruby. The code bases I’m interacting with today and will probably be interacting with for the immediate future are all in Python. It’s likely the new code bases I mess with will be in Python or Go (neither of which language, I should say, I hate). There may be a little room here or there for Ruby, but I don’t expect it to factor heavily. I did some real soul searching on this topic before I accepted their offer. It came down to this: I am more interested in APIs and SOA than I am in sticking dogmatically with one language, however much I may love it. I think that strategy also has longer legs in terms of career viability. Computers will probably be talking to each other long after Ruby and all the languages we use now are out of fashion.

Under Armour also didn’t score especially high on the social justice front. There are bright spots and dark spots and I think having a large retail marketing segment of the company has a weird effect on things (Cf. general media representations of marginalized people). However, I think this is something that can improve and that I can be helpful in making that improvement. Our entire industry (our entire society) has a long road to walk on this one, so it’s not like I was going to find a place where I’d’ve felt comfortable resting on my laurels.

At any rate, now I work for Under Armour. Which is weird to me, in some ways, but I’m really looking forward to seeing what awesome stuff we can get up to.

Looking for a Job


I left Return Path where I worked on Context.IO in September just before my daughter was born. Since then, I’ve been spending time at home, doing babby-related things. Now that the family front is more stable, I’m looking to get back into the swing of things with my career.

Hopefully, my new gig will hit some of these concepts: Ruby, social justice, APIs, hypermedia, service oriented architectures, practical design, not moving away from Austin. Only the Austin thing is a deal-breaker, and I don’t expect that I’ll find a place that I like and that likes me that hits all of these. It’s also probably not an exhaustive list, given how human brains seem to work.

If you know of someone I should be talking to or some place I should look into, let me know via email or on Twitter or whatever. I’d greatly appreciate it. Also, if you’re in Austin and just want to grab lunch or something, I, uh, have some time these days. Read on for more details.

Social Justice

I’ve talked about it a bit here. I’ve talked about it a lot on Twitter and in chat rooms and in person. Over the last few years, I’ve had a growing interest in, understanding of and concern for social justice. It started with feminism and has grown more intersectional as I’ve learned more.

This doesn’t mean I’m necessarily looking to work for a company that directly works towards social justice (though that doesn’t sound bad). I’d consider this criterion met if a company is taking active steps to hire and retain employees that don’t all look the same and supports diversity efforts in the community.


Ruby and I think the same way about things. It’s the least-bad programming language I’ve met. I’d like to use it more and I spent more time than I liked at Return Path writing not-Ruby.

This isn’t to say I’m opposed to other languages, especially where they meet a specific design or business need (Go and Rust come to mind most readily). I just… really like Ruby and think it’s a really smart default choice when picking a language for a new project.

SOA, APIs and Hypermedia

First off: I think SOA (or “microservices” if you’re not into the whole brevity thing) is showing itself to be a solid way to meet scaling demands in a cost-effective, maintainable way. The thing is, I don’t think we, as an industry, are really good at services yet. There are some exciting things going on in this area and I can see some powerful stuff coming down the pipeline (especially as this intersects with DevOps).

I have a theory that HTTP APIs are one of the best ways to get your SOA organized. It’s a well-understood, widely-used protocol with tons of library support in any language worth using in production (I don’t know if brainfuck has a solid HTTP library, though). As an industry, we’re really good at making HTTP requests fast, measuring them, optimizing them, etc. And, if you exercise the full range of the spec (all the response codes and headers), it is very expressive. I see this as a point of stability to lean on in an area that we’re still trying to figure out how to do well.

Further, I think that hypermedia has some really strong selling points when it comes to HTTP APIs. The original REST paper addresses problems that are still solved in mostly-inconvenient ways in many HTTP APIs. This is a big topic that I don’t want to get deeply into here. It’s worth mentioning that I feel like there’s some promise, here, but enough about hypermedia hasn’t been widely tested enough to have developed a range of best practices about it.

I’d love to be at a place that was interesting in investigating the above triplet of concepts and pushing the industry forward in this area. I have ideas and opinions and I want to test them in the real world. I could be totally wrong about all or part of the above… and I want to find out.

Practical Design

Ever since I read POODR, I’ve had the growing conviction that good design doesn’t have to cost your project tons of time; that there’s a right amount of thinking and talking about software design that will save you time in the not-so-long term.

Often, people talk about the dichotomy between developers who want to craft a beautiful cathedral and those who want to toss up a rickety prayer tent. I think there’s a middle ground such that you avoid the never-ship “architecture astronaut” but also avoid painting yourself into a corner by getting underwater in technical debt (so many analogies). And I think Sandi Metz was talking about that middle ground in her book.

I’d like to work at a place that has a similar sense to me about what that right amount of thinking and talking is. I don’t know how to describe the amount, exactly, so I’m kind of hoping that this is something that will reveal its self in interviews.


I was born here. I grew up here. My wife did the same. Our parents and siblings live here. It doesn’t snow here. The food is yummy here. I own a house here. The Ruby community in specific and the startup community in general agree with me here. I could go on and on, but I don’t foresee my moving away from Austin without radical changes in my personal situation.

Also, with communication technologies being what they are, I find it sort of silly if a software company can’t figure out how to do remote reasonably well. It’s something my business unit at Return Path decided we wanted to be good at and were then surprised at how easy it was: most of the problems evaporate in the face of any attention at all. Heck, using Slack alone solves a giant chunk of the problems if you use it religiously. Good email culture solves another huge swath.

Scenes From the Post-apocalypse

I’m on a bit of a hiatus from role playing because we have a new born at home, now. Until she’s easier to deal with in the evenings, I don’t really want to stick my wife with bed time for the 3-year-old and the 3-month-old all alone while I tell stories with my friends. Seems like kind of a jerk move.

But I’ve been jonesing really hard for it. And since I learned what Apocalypse World was, my group hasn’t actually gotten a chance to give it a good, honest play.

So, since I’m supposed to “daydream some apocalyptic imagery” and be “developing [my] apocalyptic aesthetic”, as well as “to cultivate an apocalyptic aesthetic in [my] players too,” I started emailing random snippets of Apocalypse World inspired imagery to my players.

In an earlier stage in my career running role playing games, I might have hoarded these, worried that I wouldn’t be able to come up with something similarly cool later, and confident, for some reason, that I’d be able to remember this stuff well enough to use it at the table. But, like, what?!?

At any rate, I thought someone on the internet might find them interesting, entertaining or useful. I’ve cleaned them up just a little from the original emails.

The Ghost in the Jungle

The vegetation here is dense. Everything smells like rotting plant matter. The light level varies wildly, based on how much wan, green sun filters through the canopy. Everything that’s not a dark brown is tinted some shade of green. The trees dwarf everyone. They’re definitely taller than any building in the hardhold, and wider at the base than Vee-dubb’s van is long. The air is still as death; the only things moving are the bugs, bzzzing and stinging, nearly invisible to the naked eye.

The lot of you hike on. The heat is oppressive. It’s not like the sun bearing down from on high out in the Tire Wastes. This is a more encompassing, much wetter heat. It is hard to breathe, and sweating does no good at all. Everyone is drenched and gross.

Fleece is the first one to spot it: pale white and hard as rock, covered in fine spiderwork of cracks but feeling no weaker for it. Beneath the turtle shell of ceramic is a mass of black machinery, dead and busted with grubs and mushrooms growing underneath. After that, the frequency of seeing smooth white amid the vines and roots increases steadily; you’re headed the right way.

Your little group walks in silence, minds on your feet and the stifling humidity. No one is in the mood to talk any more. Then there’s a funny snicker-snicker-snicker sound and Jollyby cries out, blood erupting from exit wounds in his chest. He collapses into a giant fern, staining the leaves red and doesn’t even gurgle. Everyone freezes, and you can see a white dome, with black metal peeking out from underneath it swiveling slowly away from where Jollyby was standing, not as dead as you thought.

What do you do?

This was the first one I sent out, and I didn’t explain to my players what I was doing, so one responded with this callousness:

Shit. Not again.

A flare to the “face” always fucks with the heat-sensitive abominations. At least for a few seconds.

Like bouncing a baseball off the wall in the hardhold. Hit the same spot, again and again. Practice makes perfect, they say.

I visualize that spot as bein’ right in the center of that black maw of metal and put the flare right on the money.

Should buy me a few seconds. At least enough time to get under the ferns and start circling my way around to Jollyby.

I like that necklace he been wearin’.

First come, first serve.

Savages, Cannibal Savages

So, Jav, Kartak, you’re out there, now, among the Tire Wastes at mid-day. Sucks for you. The hidden mouth of the tunnel recedes at a pretty good clip, if you do say so yourselves, given your current state of abuse. The heat rolling off the piles of half-melted black rubber starts to get to you real quick and you realize that, while the tunnels were full of murderous, howling savages, bent on eating and cooking you (in whatever order), at least they kept the sun off. That shit is brutal.

Then you hear it: the hue and cry of a cannibal pack calling for your blood. Looking over your shoulders, you can see between mounds of rotten tires a group of a half-dozen or more of the fuckers, armed up with random bits of sharp and heavy instruments of violence.

If you’re quick, you could maybe squeeze in under some of the local “geography” and hide it out, but it means getting in there among all those tires that have been baking in the sun for hours and hours: even if you weren’t dehydrated from your imprisonment, not a pleasant experience. Other than that, it’s mostly either stand and fight, or hope to outrun them to where Vee-dubb’s waiting with her van. If she’s waiting with her van.

What do you do?

Another player responded this time, with this visciousness:

Jav slips a holdout from the small of his back and puts a round through Kartak’s femur while his former friend stares at the hounding madmen. Tears trace ephemeral trails across filthy cheeks as he pushes towards the pickup. With body and lungs burning from exertion (the ambient vaporized rubber helps too), he promises the world will know the noble end of Kartak and how he sacrificed himself to save his dear friend Jav.

The Market

So you’re sitting out there the rest of the night, watching Imam’s store front. Eventually, the angry red circle of the sun starts to creep up into the sky, pouring pink light over everything. Before the sky is much light at all, people start to trickle into the market space in ones and twos. Some are setting up shop, there’s Ula, getting water from the well for her folks; her dad’s been sick recently with a fever. Dustwich rolls his food cart up next to the news board and starts getting it going. Slowly, the market comes to life.

It’s a while before the first strangers show up, mostly folks staying at Chin’s flophouse. The first travelers won’t arrive until late afternoon, generally.Then you spot it: someone you don’t recognize, a scrawny bald someone in a nomad’s poncho, looking around furtively. They back casually down an alleyway next to Imam’s that you know for a fact is a dead end with no doors on it.

What do you do?

The Mead Hall

You open the doors and there Swiss Miss besits her throne: leather clad and radiating danger. At her feet sit two waste hounds, snoring with eyes open. The air is smokey from the torches lining the walls and the large rectangular fire pit that runs the center of the room. At two long tables, her gang sits at their leisure. All are men and women of violence, armed with guns of wide description and pointy instruments of death both vile and various. All eyes turn to you as you enter.

What do you do?


They call it opening your mind, but it’s more like the maelstrom burns the world away around you. Your body turns to ash and blows away in a furnace wind. Everything around smells of charcoal and gasoline, the light is all orange and red with dark, oily shadows.

As smoke billows through your consciousness, you see that Keeler isn’t as alone as she looks. She’s got a line of compatriots lying low just behind the rise she’s standing on, five or six of ‘em, all armed.

And now that the flame has shed some light, you have to feed the fire: When was your first kiss? With whom? Why don’t you like to think about them?

The Settlement

The top of the ridge is hot and dry under your chests. Passing the rifle between you, you can see some better detail about the settlement through its scope.

There’s some amount of walls, but not all the way around: either not finished being built or some damage done. There’s a collection of buildings inside, adobe (the same color as the surrounding wastes) and scrap metal, mostly. Not of uniform heights, but all one story.

There’s a kind of square in the middle of town. Around a well and a market, maybe. A complex arrangement of canvas and plastic sheeting suspended, taught, between ropes and wires like sails provide shade to the square. Or would, except that substantial portions are ripped and busted, hanging down and blowing limply in the hot wind.

And that’s the other thing: There’s no people in sight. Did they see you and they’re hiding? Are they all gone? Did something bad happen here? Is it still happening? If anyone’s left, would they assume you’re here to help or hurt? Would they cower or attack? From this distance, there’s no way to know.


Do you go on down there, or try to work your way around and move on or what? What do you do?

HAL Client Update: Cetacean

After writing my last post, I used the code presented therein in production a few more days and realized I wanted just a smidge more power. Specifically, I wanted it to handle HAL’s embedded resources. So I added that and then the other night, I pulled it out of that project, broke it up into files, named it after sea animals and pushed it to Introducing: Cetacean.

Now, I realize my last post was all, “Do we need HAL clients?” and shit. But let’s be real, even 42 lines is a HAL client. Or… whatever, depending on what your definition of “client”. In fact, the design of Cetacean is basically driven by thinking about what “client” means and what I felt like I needed a tool for with respect to HAL documents.

Basically, Cetacean helps you deal with HAL documents, it doesn’t really help you with hypermedia APIs. The general work flow is that you make a Faraday client (configured however seems best to you) and make a request to some URI. You feed the response to Cetacean and then operate on it. You might get a URI out of it (from a link, say), which you can then feed back to your Faraday client, which response you can feed to Cetacean, again, etc.

Perhaps an example would be helpful:

api ='') do |faraday|
  faraday.headers['Accept'] = 'application/hal+json'

root =

At this juncture, you can ask root about some stuff. It’s an instance of Cetacean::Responce. It proxies some methods back to the Faraday::Response, and otherwise is mostly sugar for getting things out of the HAL document.

root.success? # => true
root.status # => 200
root.response # => The `Faraday::Response` you passed in.
root.body # => '{"foo":"bar","_links":{"self":{"href":"/"},"users":{"href":"..."}}}'
root.hal? # => true
root.attributes # => { 'foo' => 'bar' }
root['foo'] # => 'bar'
root.links # => { 'self' => { 'href' => '/' } }
root.get_uri(:self) # => A `URITemplate` object for you to manipulate.

So if you want to follow the ‘self’ rel, you use get_uri method to get a template, do whatever you want with it (probably to_s and expand are the most common cases). And then… do whatever you want with that. Make another HTTP request? Get it tattooed on your stomach? Cetacean doesn’t really care.

Continuing on, imagine further interactions with an API. Notice that at each stage, Cetacean deals with the HAL, and then gets out of the way.

users =
user = users.embedded(:users).first

Assuming that the ‘users’ rel was some document that embedded an array of documents under the ‘users’ rel, user is an instance of Cetacean::EmbeddedResource. It behaves mostly like a Cetacean::Response except is doesn’t have a request object to proxy or refer to. Ideally, you shouldn’t have to keep track of which came from where once you’re dealing with a document.

important_blog_post = 2)))
interesting_blog_posts = 'interesting')))

Just another couple of examples of following different links, both of these requiring expansion.

This is certainly more wordy than using a more featureful library like Hyperclient or whatever. I feel that this gives you a lot more control over how you deal with the documents you get back. If you unexpectedly get back an invalid body, Cetacean won’t barf trying to parse it like JSON, if you get back 'image/jpeg' instead of 'application/hal+json', Cetacean makes it easy to deal with that however is most appropriate. If you need to do some fancy, weird-ass configuration of Faraday that’s super specific to your use-case, then you don’t have to worry about what a middle-man library might do to your connection configuration.

Anyway, I guess I wrote another gem. If you use it, I’d be interested to hear about it. If you want to help, feel free. It’s on Github.

Thinking About HAL Clients

More and more, at work, we’re talking about service oriented architectures. Mostly, these are very small apps that deal with just a few concerns. Since we foresee having lots and lots of these little mini-services, we decided we’d need to make some decisions up front about how they’re inter-operate. This is sort of in the spirit of convention over configuration.

More to avoid having to re-make the decision about what shape responses from these services should take every time we start a new one than for any other reason, we decided that all these services should speak HAL. This way, we can get good at dealing with HAL and once you grok how to talk to one service, that knowledge will transfer readily to others. We picked HAL over other formats we considered basically by typing out an example response off the top of our heads and then seeing which existing format looked the closest. So scientific.

Since that time, I’ve spent a fair amount of time monkeying with HAL and related hypermedia issues. There are a lot of angles, here, but I wanted to start off by writing about the idea of a HAL client.


Initially, I started using a Ruby library called Hyperclient. It basically abstracts parsing and navigating HAL documents and making requests to the links in them away from the developer using it. At first, I thought this would be great. However, the more I used it, the more I felt like it was doing more to me than for me.

In it’s effort to keep the developer from needing to know the HAL spec front to back, it is pretty complicated and has a lot of corners for edge cases to get stuck in. And, really, since HAL is so readable, it ends up just mapping hash access to method calls in a lot of cases.


I really hope I don’t have a NIH complex, but… I do use Arch Linux because of the level of fiddling it allows with how my laptop behaves… and I tune and tweak my .vimrc and .bashrc so my environment is just so. Thus, it shouldn’t really be surprising that when I wanted more control, I decided to build something from scratch (sort of).

The other day, after encountering some weird interaction between Faraday, Hyperclient and certain features of WebMock, I decided to see how hard it would be to rip Hyperclient out and replace it with something dumber and simpler. After talking it over with the team, we decided the best course would be to time-box it to a day.

Here’s the 42 lines I replaced Hyperclient with:

require 'forwardable'

class HalResponse
  extend Forwardable

  def_delegators :response, :status, :success?, :body
  def_delegators :hal, :[], :fetch

  attr_reader :response

  def initialize(response)
    @response = response

  def hal?
    response.headers['content-type'] =~ %r{\Aapplication/hal\+json}

  def links
    hal['_links'] || {}

  def get_uri(rel, expansions={})[rel.to_s]['href']).expand(expansions)

  def attributes
    hal.except('_links', '_embedded')


  def hal
    @hal ||= parse_hal

  def parse_hal
    self.hal? ? JSON.parse(response.body) : {}
  rescue JSON::JSONError, TypeError

The way this works, is you build your own Faraday object, you make the requests yourself, then you feed the response into a HalResponse constructor to monkey with it. If you want to follow a link, you call get_uri and feed that result to your Faraday object. A short example:

client ='')
root =

posts =
search_results =, q: 'Ruby')))
new_post =, title: 'Blah', body: 'whatever')))

It’s important to note that my 42 lines don’t deal at all with embedded resources and are tailored to handle cases presented by a specific API of a specific service I’m coding against. But that’s actually part of my point: Do we need HAL clients? Is the document format that hard to grok?

Since HAL (and other hypermedia types) rely on the semantics of HTTP pretty heavily, it seems much more important to have a robust HTTP client. Dealing with the specially-formatted response bodies seems like a separate issue to me. I may expand the above class as I continue to use it in production, but I kind of like the wordy, do-nothing-for-you kind of way it works.

Ben’s Gem Maintainer Handbook

At work, recently, we were discussing internal gems and how to deal with releases and crap. Of course, because this is a topic, I have opinions on it. I can’t help myself.

Actually, someone was like, “Why do we do it this way,” and someone else was like, “I don’t know, ask Ben,” and I was all, “Ranty rant-ra–You know what? I’ll just write a blog post.” So, now you’re all inflicted with this. You have Bob and Ryan to thank for it.


So this is pretty simple, and other people have explained it better than I can. You should be using Semantic Versioning for your gem. You can read the full spec, but I’ll break down the general idea real quick.

Version numbers are 3 segments in the format major.minor.patch. You increment the major version if you’re shipping any backwards-incompatible changes. You increment the minor version if you’re adding backwards-compatible new features. You increment the patch version if you’re just doing bug fixes. When you increment one segment, all the segments to the right reset to 0.

This way, a consumer of your gem can tell by looking at the difference in version number whether the changes should be backwards compatible or not (major version changed) or whether that new exciting feature they’ve been waiting for might be in (minor version changes).

Version Number

If I’m in a REPL with your gem loaded, I should be able to ask it what it’s version number is, so put the version number in the code. Ideally, I think, it should be a string of the numbers. Some people seem to like to have MyGem::VERSION be how you get it. Personally, I like to provide MyGem.version, as well.

If you do this, you can then refer to it in your gemspec, where you officially set the version of the gem. You should put it alone in it’s own file, though, so you don’t have to load your whole gem just to interleave your version number into the gemspec.

Keep a changes file. There are a few file names that seem to be widely recognized, but I like the best. I prefer not to keep this information in the README just to avoid cluttering that file for people who are interested in documentation or contribution guidelines.

My file has a <h1> at the top that just says ‘Changes’. I don’t have strong opinions on that part. However, the following bit I have very strong opinions on.

You have several sections, following the title. Each section is an <h2> that is the version number of a release followed by a bulleted list of the changes since the previous release. Each item in the list should be a brief summary of a bug fix or feature–no reason to replicate your entire commit history here. Personally, at least for publicly available gems, I like to also credit the author of the change by name.

Each of those sections should go in descending order of version number so that the newest stuff is at the top. There’s also a special version: ‘Unreleased’. Between releases, you don’t yet know what your next version number will be. Will you add a new feature? Break backwards compatibility? Who knows. So I log changes as they’re merged to an ‘Unreleased’ section of This way I don’t forget what’s in and it’s easy for someone to see what kind of stuff is coming in the next version (or what’s in master that isn’t released).

Rarely do people sending me Pull Requests add their own entry to, so usually, I’ll merge their code, and then go add an entry for their change myself. However, I would be delighted if a contributer wrote their own entry.


The point under discussion at work fits into this category. I always bump the version number a lone commit, apart from any feature branch or other changes. I feel like there are a couple of advantages:

  1. It provides you an opportunity to review in it’s final state as you decide how you need to change your version number for release.
  2. It means that you can add a feature that, as you write it, seems like it’ll be the last one before a release and then at the last minute think, “Oh, just one more,” and still have the version bump be the last commit before release.

Relatedly, tag your release commit. I just tag mine with the version number, but you can put a ‘v’ in the front if you like. I don’t care. The point is to make it easy for a consumer of your library to go to Github and easily find the commit that matches whatever released version they’re using. Make sure to push that new tag up to Github.

When I’m ready to release, I do like this:

  1. Review and select a new version number.
  2. Update the version number in the code.
  3. Change the ‘Unreleased’ heading in to the new version number.
  4. Run gem build my_gem.gemspec. If it doesn’t build right, stop and fix it. Don’t commit the new version number as part of that fix.
  5. Commit the version bump changes.
  6. Tag the new commit with the version number.
  7. git push && git push --tags && gem push my_gem-1.2.3.gem
  8. rm my_gem-1.2.3.gem.

I’m sure the above could be automated, but it never seemed like enough of a pain in the ass to be worth my while.

So them’s my opinions on gem maintenance. If you tweet or email me questions, I’ll update this post with answers.

Never Type Bundle Exec Again

Sometimes people complain about having to type bundle exec before every freakin’ command in a Ruby project. Honestly, I think the benefits Bundler gives you outweigh that downside by a huge margin. However, there is good news: You can use this one weird trick to never type bundle exec again.

OK. It’s actually an option of two weird tricks. And then a bonus trick. This joke is ruined.

Somewhat Involved, Works Everywhere

If you’ve got Ruby installed, you can do this trick. It’s a little hacky and comes with some downsides.

First up, make ~/.bundle/config look like this business:


This will tell bundle install to always run as if you passed the --binstubs=bin option. Now, when you bundle up a project, it’ll drop wrapper scripts into the bin directory of your project that ensure the correct Bundler environment is set up before running their normal stuff.

As a courtesy to everyone you share a project with, when you do something like this which will litter your project up with files to do with your personal set up, you should make sure you don’t commit them to anything. So go to your global git ignore file and make sure it includes this:


Here’s downside number one: You will probably have to override this for specific projects. For instance, gems often ship with a bin directory with files to do with the gem. You’ll want to make sure those aren’t ignored. If you explicitly git add them, they should be tracked by git thereafter, but you have to go out of your way. In particular, a Rails project contains wrappers for rails, rake and bundle in the bin directory and those should be committed to the repo… and not over-written by your bundle install binstubs. So take care, there.

At this point, you could stop, except you’d have to type bin/ in front of every command, instead of bundle exec. Sure, it’s shorter, but still annoying. The next thing to do might be to prepend ./bin to your $PATH so that your command line looks there for commands first. Downside number two is that there are some negative security implications to this, so I for sure don’t recommend it for servers, but I’ll leave it up to you whether you do it on your personal dev machine.

Less Involved, Requires rbenv

“But, Ben,” you say, “I want to be just like you so I use rbenv.” Well, you know, that’s flattering and I have to say you make some good life decisions, friend. Let me tell you about some nice tools.

If you use rbenv (and I like it so far), then you can take advantage of it’s plug-in system. Probably you’re already using ruby-build as a plug-in to install Rubies. I have two more for you: rbenv-gem-rehash and rbenv-binstubs.

You can read more in the READMEs of those projects, but in brief, you install them to your ~/.rbenv/plugins/ directory, then make your ~/.bundle/config look like this business:

BUNDLE_BIN: .bundle/bin

Undo any steps you may have taken above (like ignoring bin) and shit should be taken care of for you. Now you won’t have to rbenv rehash or bundle exec! Rockin’.

Note: The .bundle directory of a project that uses Bundler should already be ignored in git, so tossing your binstubs in there should protect you against barfing them into a repo unintentionally. Rbenv-binstubs handles making sure they’re in your path for you.

Bonus Trick: alias be

I kinda lied to you. I’m sorry. You may still have to type bundle exec on occasion, even with nifty rbenv-related goodness. Things that aren’t gem commands don’t get binstubs from Bundler: notably, the gem command. For me, this most commonly comes up when I want to see what the gem list is that Bundler’s resolving.

Doing gem list will show you all gems installed for the active Ruby. No help. So you can do bundle exec gem list and Bundler will do it’s path-related mojo and then execute gem list for you. Nice, but typey. So the bonus trick is to add this line to your .bashrc (or .bashprofile or whatever madness your system might use):

alias be='bundle exec'

Now you can just be gem list, which sounds sort of like an existential confusion to me, but involves less typing, so… win!

Final Caveat To All This

One last thing that’s important to remember with all this: whenever you do this kind of optimization of your local system, whether it’s installing vim plug-ins or putting set -o vi in your .bashrc or whatever, you have to keep in mind that it’s not portable. When you shell into your alpha server to tail some logs or debug something, you won’t have this stuff. So while you may never type bundle exec again locally, you should remember that it’s still there in the background, and remember that on machines you didn’t set up, you’ll still need to type it.

Social Justice Is Made of Empathy

I was listening to episode 101 of The Ruby Rogues with Ashe Dryden as the guest. The episode includes some of what social justice folks call “101 work”, which is the sort of entry-level explanatory teaching that it takes to get someone from something like “Isn’t a code event specifically for girls, sexist?” to, “That’s not cool”.

Anyway, I really liked the episode, and I recommend you go give it a listen, especially if you’re new or entirely unintroduced to the topic of social justice. They talk a lot about feminism specifically, since there’s been several high profile events related to it this year so far, but they talk about intersectionality, too (like what is is, if you don’t already know).

In this post, I want to address one specific topic they talked about. One sentence, in a way. As part of a discussion about calling people out on comments that are exclusionary or otherwise inappropriate, Ashe was saying that simply saying, “That’s not cool” can have a powerful effect, sending the message that that kind of thing isn’t socially acceptable within the context it was said and that most people will modify their future behavior accordingly.

As a follow-up to that, Avdi Grimm asked if there was ever a time that you’d say something, someone would point out that it made them uncomfortable (or whatever) and you apologized, but decided that whatever the statement was, it was so much a part of who you are, that you knew you’d say it again in the future. I’m paraphrasing, here, hence the lack of quotes. In answer, they talked about a few things, but someone said something else and the conversation kind of got distracted. However, I’d like to address it somewhat.

The flippant answer to the question is, “Of course.” I mean–if I say something like, “I really, really like wearing argyle socks,” and you’re like, “That comment offends me,” there’s not a whole lot I can do for you. Assuming I don’t just think you’re trolling me, I would probably apologize because I don’t like to make people feel bad, but… I seriously wear argyle socks every day. I love that shit. I am likely to express that idea in the future.

But if we’re talking more seriously, thinking of a comment that actually addresses people in some way (instead of socks), I think the idea becomes really interesting (I’ll leave it as an exercise to the reader to come up with an appropriately offensive remark). If you say something offensive or exclusionary, I’m going to give you (and me) the benefit of the doubt an assume it’s because you didn’t realize it would be so. You’re a good person; you don’t enjoy ruining other people’s days.

After making your comment, someone in the group (or near the group over-hearing) says something to you about it being inappropriate and you apologize. Great. How, though, do you get from, “I didn’t realize that was racist,” to “but that thought it so intrinsic to my being that I don’t care and I’ll say it again later”? The only method I can see to get there is if “I am an empathetic human being who cares about others” isn’t a part of how you view yourself.

Personally, I am bad at empathy. I have a hard time reading people sometimes, but I still like to think of myself that I’m empathic. If I manage to figure out that someone was hurt by me, I feel bad. I want to make it better. And in the scenario laid out above, we’re removing that, anyway. Above, I’ve said something and someone flat out told me what was going on, in case I didn’t pick it up.

So if some aspect of that remark is intrinsic to my self image and empathy is intrinsic to my self image, then they’re in competition now. And, I guess, you have to be real with yourself about which one is actually more important to you. Possibly with observation, not introspection. Personally, I’d like my personal narrative to be more about being empathetic to other people than about protecting my ego or whatever.

So, I guess what I’m saying is: If someone near you points out that something you said is out of bounds, and you find yourself saying, “No, my gay friend always jokes around with me that way and he’s not offended,” then you are failing at empathy. At least from the standpoint of someone who is basically sitting on a mountain of privilege (me), social justice isn’t about gay couples wanting to “ruin marriage” or women wanting to invade and displace all our special boys club professions and hobbies or anything like that: It’s about giving a shit about other human beings.

LOL Civil Liberties

The other day, Carol Nichols linked to an interesting article. It is a transcript of a conversation between John Cusack and Jonathan Turley about politics. We traded a few tweets and I said I’d get back to her, but… tweets are short and shit is complicated and, here’s a blog post. I don’t generally talk a lot of politics here, but, screw it. It’s my blog.

So, before I read the piece, Carol was talking about deciding not to vote at all for the Presidency and some stuff about not letting the good things a person has done excuse the lines they’ve crossed. Hopefully I’m not mischaracterizing her statements due to some misunderstanding on my part. In any case, I’d said something in reply about choosing the lesser of two evils (I don’t by any means consider myself a Democrat, but the Republican party is… way off the rails these days). Then Carol said something I hadn’t really considered: If both options have crossed a threshold of minimum-allowable-bad, then choosing the least-bad rather than demanding better enables increasing badness. So I said I’d read the article and get back to her with my thoughts.

Having read the thing (you did, too, right?), I have to say I see what Carol was saying much more clearly. Surprise, surprise. The thing that stood out to me was that I’d heard about Obama’s whole authority-to-assassinate-US-citizens thing when it came out. I heard about it and thought, “That doesn’t sound right.” And… then forgot about it. Or, more accurately, I filed it under “Bad Shit In The World That, Thank Eris, Doesn’t Affect Me” and then got all riled up about health care and tax breaks for the rich at the expense of the rest of us, etc. How did that happen? How did I let that happen? Talking about how the Whitehouse has sold us ideas is true in a sense, but also false in the sense that it can sound like we are actors without agency. They don’t have some kind of mind control over us. I have to accept that I wasn’t really looking at the world as clearly as I’d like or as I’d been telling myself I was.

Some stuff that’s bad in the world and doesn’t affect me, I can live with ignoring (I think this is only pragmatic). But some stuff should go in the other file: Not OK, Damnit. Things like Sexism, Racism, Child Abuse… and The President of the United States deciding he has the authority to unilaterally assassinate people (whether US citizens or not). Ugh. So, OK. I’m upset about that now. And also upset that I wasn’t appropriately upset about it when I first learned of it. That feels like progress.

That issue when paired with the whole unprosecuted war crimes thing and the implications that has for mediating international interactions and Nuremberg precedents really drove Turley’s question home to me: “Morally, are you comfortable with saying, ‘I know the administration is concealing war crimes, but they’re really good on healthcare?’”

And, you know what? That’s a really depressing question to be in a position to even be asked. War crimes are serious shit, you know? They’re the list of things that we’ve agreed we don’t even wish on our enemies. It’s the list of things that super heroes won’t stoop to because “if we do, we’re not better than them.” They are exactly the stuff that we’ve decided the doing of differentiates the Good Guys from the Bad Guys. So if I’m OK with the POTUS doing them, or allowing them to be done or protecting those that did them, then I’m comfortable being a Bad Guy. And fuck that.

So, I guess we’ve established that I feel like there’s a problem and that I’m not happy with either of the candidates put up by the US’s major parties. The next question is: What do I do about it? As part of this discussion, there is the idea that voting makes you implicitly culpable and that if you refrain, you can be said to be calling for better candidates. The culpability angle, I agree with. But I’m also really wary of casting inaction as activism.

I am not an activist by nature; I’ve never been to a rally or demonstration. I’ve never occupied anything except various chairs and sofae mostly in front of video screens. I am also, by nature, physically lazy. So anything that sounds like something I’d do doesn’t seem like it should count as activism. Like changing your Facebook avatar to reflect some fad cause, or writing a ranty blog post about politics (heh). So on that front, I find the “so don’t vote” thing kind of… dissatisfying.

Also, there’s a sort of game theory issue, here. And this may be an illustration of why we’re all just screwed, rather than a justification for an individual’s actions. But this also bugs me: If I was planning on voting for Obama (I was), and now I don’t (undecided, still), then I am letting someone else decide which candidate wins. If I do vote, then I’m at least increasing the chance that the fate I’ve selected is the one I’ll suffer. It feels very Prisoner’s Dilema-ey to me. That’s not an excuse, but it seems to predict that getting a low enough number of people to vote such that the parties notice there’s a reason is infinitesimal.

Of course, on the other hand, not voting is throwing away a resource in a sort of a similar way as voting for a Democratic Presidential candidate in Texas is, so my vote or non-vote is actually pretty unlikely to affect which way my state’s electoral votes go. If I lived somewhere swingey, it would matter more. I guess the decision comes a little more easily, then.

Anyway, I’d love your (thoughtful, respectful) comments and reactions. Especially, I’m interested in help expanding and deepening my thinking about this stuff. I’m sure there’s prior art on some of these ideas that I’m unaware of.

Install Ruby Enterprise Edition With Ruby-build on Arch Linux

I run Arch Linux on a computer, if I have a choice. I recently installed it on the MacBook Air my employer bought me (which saga is another post entirely). One of the things that I like about Arch is that they don’t do big releases every X-period of time; the package repository is updated on a rolling basis. So I can get the latest version of whatever much sooner than my Ubuntuan brethren.

That’s awesome, but also has some costs. One of those costs is that gcc gets updated for me way sooner than it does for people releasing Ruby versions and sometimes there are weird things that older releases of the compiler were more forgiving about or interpreted differently or whatever. So in order to get our app at work that we haven’t yet ported to Ruby 1.9.2 to run, I need to have REE installed. This is how I got it done. This is one of those blog posts that I hope gets indexed so that the next time I have to do this and I ask Google about it, it will show me my own blog post.


I like rbenv. A lot of people prefer rvm. I don’t want to get into pros and cons or whatever now, but because I use rbenv for managing multiple ruby versions, I use ruby-build to install multiple ruby versions. The way ruby-build works is by executing recipes, which are pretty simple. Here is the one I wrote to handle the install. It’s just a variation on the stock REE install recipe from ruby-build.

build_package_stdout_patch() {
  wget ''
  patch -p1 < stdout-rouge-fix.patch

install_package "ruby-enterprise-1.8.7-2011.12" "" stdout_patch ree_installer
install_package "rubygems-1.6.2" "" ruby

I won’t get deep into the details, but let’s start with the last 3 lines. Ruby-build executes each of these directives in turn. The first of the three sets up the compiler and the next two each take a series of arguments. The first two of those arguments are what it’s installing and where to get it. Any after that (you’ll have to scroll right) are telling it what to do with it, once it’s downloaded it. It will run the last arguments in the order given. So that brings us to the function I added at the top: build_package_stdout_patch.

When you pass those ending arguments into install package, it will look to execute a function by the name you gave it prepended with build_package_. So the function I wrote downloads a patch for a bug having to do with creating rogue references to STDOUT, then issues the patch command to work it into the REE source. I don’t know a lot about the patch command, so there’s a good chance this could be done more nicely (see below). After that, it runs ruby-build’s standard ree_installer task wich builds and installs the REE source.

Running It

When you’re using ruby-build and rbenv together, you get a nice command called rbenv install. You can either pass it the name of a recipe that ruby-build already knows about or the path to a recipe on your hard drive somewhere. So, in the directory where I had saved my recipe, I ran:

$ CONFIGURE_OPTS="--no-tcmalloc" rbenv install ./ree-1.8.7-0211.12-stdout_patch

Note: There’s some kind of problem with tcmalloc and the newest gcc. Or something. I don’t really understand, but since this is just for local development, I decided not to worry too much about performance and skip it. If you set the environment variable CONFIGURE_OPTS, ruby-build will pass those options along in it’s build process. So off it goes to the races. Then, I get this output:

Installing ruby-enterprise-1.8.7-2011.12...
--2012-02-03 12:07:35--
Connecting to||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 719 [text/x-patch]
Saving to: `stdout-rouge-fix.patch'

100%[======================================================>] 719         --.-K/s   in 0s

2012-02-03 12:07:36 (68.9 MB/s) - `stdout-rouge-fix.patch' saved [719/719]

can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
|diff --git a/lib/mkmf.rb b/lib/mkmf.rb
|index c9e738a..7a8004d 100644
|--- a/lib/mkmf.rb
|+++ b/lib/mkmf.rb
File to patch: source/lib/mkmf.rb
patching file source/lib/mkmf.rb
Installed ruby-enterprise-1.8.7-2011.12 to /home/ben/.rbenv/versions/ree-1.8.7-0211.12-stdout_patch
Installing rubygems-1.6.2...
Installed rubygems-1.6.2 to /home/ben/.rbenv/versions/ree-1.8.7-0211.12-stdout_patch

Pay particular attention to the last half of this. After the progress bar, patch gets confused. That’s because the patch is really for Ruby 1.8.7 MRI, not REE. So it complains about not being able to find the file it wants since the projects have slightly different directory structures. You can see where I entered the correct path (basically, I just prepended the source directory). With that information, the patch applies cleanly, it builds REE without tcmalloc and now I have a ruby called ree-1.8.7-0211.12-stdout_patch. Hopefully that’s helpful to someone besides me.