Zack Hubert

Co-Controllers in Rails

Four months ago, I started work on a new product. My coworker and I were talking about strategies we wanted to take on this green field project, and we came across a thought-provoking gist by DHH. I’m not fully aware of the whole origin story of it, but his Tweet indicates it’s a pattern they use in Basecamp to avoid bloating a controller. Instead, they divide actions by domain and have related controllers, ‘co-controllers’, tackle stuff for their respective domain. Makes sense.

So we decided to give it a shot through the whole course of the project to date and I have to say it’s been quite useful. I feel really confident that this project is going to be able to grow more gracefully than previous large scale projects I’ve written. Why? I think there are a few things that contribute to it’s helpfulness, but let’s start with a reminder on some of the pain points large projects have.

The Dark Side of Why I Write Software

Motivation is a big part of programming for me. Why I do what I do…why write programs when there are many other options for what to do with the hours in which I work? And closely related, why write this kind of program vs another kind of program?

The answer for me is easy, but you won’t believe me. It’s trite…it’s expected…and heck, even an HBO Series is making fun of this part of Silicon Valley, but oh well…here goes:

I program computers to make the world a better place.

I’m a devout optimist and in a past life, figuratively speaking, I’ve gone on record at conferences in front of 2000+ people to the same effect. I was being genuine, that’s really who I am. The trick though, is it’s not for any reason you could probably think of…

An Amazon Story

This last week I was sitting with friends around a campfire and told the following true story. They found it rather interesting, so I figured it was worth retelling. The truth is, my career has been a really weird one…there’s nothing linear about any of the progression through work that I’ve chosen. It has been a truly wild ride, but I’m getting ahead of myself.

Amazon. 1999. It was a totally different company than it is now, though in many ways it’s probably still Day 1. Back then, no one believed in Amazon but us…the insiders, those that had drunk the kool-aid of the best business model for commerce (e-commerce…what a funny name now). There were so many people on “the street” that liked to write these scathing “Amazon will explode in a fiery ball of bankruptcy” stories that even the stalwart had their confidence shaken from time to time. I mean, how many times did I have to explain that I worked for a company that made no profit…sigh. Anyway, from the vantage point of 2014, it’s really easy to think it was a foregone conclusion, but for those of us in the “earlyish” times, it was an exhilirating wild west adventure.

Sorting Photos by Exif Date

Admittedly this is way off topic, but I figured I’d document how I organized my former iPhoto/Everpix library.

After the Everpix shutdown, I had a huge directory of pictures all with recent mtimes. This was not ideal.

As I’ve been thinking of moving to Google Storage since it’s so cheap now, I wanted to have at least some organization to all these pics. If you are following along at home, I recommend making a backup first.

Deploying a Golang Project to Heroku

The short version is it’s ridiculously easy!

I recently made a Bible reader that uses the Spritz-like Rapid Serial Visual Presentation speed reading technique. I wrote it in Go and I wanted to easily host it…Heroku to the rescue in 3 easy steps:

Setting Up Go

Having helped a couple dozen people get going with Go, I know that one of the sticking points is getting their workspace setup correctly. If you are familiar with UNIX, you can skip this post.

When you boil it down, you need to:

  • Install Go
  • Make directories
  • Set environment variables

Install Go

99 times out 100 using Homebrew will be exactly what you need:

brew install go

After it finishes, make sure you can find it:

which go

If things are setup correctly, your prompt will be showing the path to Go. Good, you’ve got Go.

Introduction to Go (Golang), Part 1

If you read this blog for any amount of time you’ll know that I really like technology, specifically web development technologies. I’ve written about my experiences with Ruby on Rails, Batman, and a few curiosities along the way.

But my last post was something different, it was about Go. In a lot of ways it was the culmination of a journey, without trying to sound too weird, it was also the start of one.

Normally I don’t write about something until I feel like I have a decent grasp on it. So even though I started looking at Go over a year ago, I didn’t write anything about those experiences. At the beginning I was tempted to write about how Go was missing certain things…but that would’ve been premature. Now having used it for a bit longer, I understand it a lot better, though I still consider myself a novice and will likely be embarrassed about these posts in a few months (the perils of learning).

So now that I’ve taken a few more steps, I’m ready to write about getting started, so that other people coming from a similar background could skip the confusion and go straight to the good stuff….enjoying Go for the awesome language that it is today. So let’s get started!

Solving a Hard Problem for Ruby With Go

The Problem

About a year ago, I was tasked with solving a hard problem (a tricky resource reservation problem with arbitrary quantities and spans). As with all problems, there were constraints: in this case use Ruby, use MySQL, make it respond in under 100ms, handle spikey traffic. This was a computationally intensive service for which no regular caching was possible so the only plausible solution (after eliminating many options) was adding a partially precomputed table to the database which could shortcut some of the calculation (ok, so it’s like a cache, but it’s an incomplete one).

In this way, Ruby could amortize out the calculation (a little bit on update, a bit little bit on read) and then also employ some pretty crazy SQL to help speed it all along.

Special Note: It may sound like an easy problem, but after you work on all the cases you have to deal with, you’ll realize it is in fact a hard problem for Ruby to solve with the given constraints.

Upgrading Batman

Having just completed an upgrade of a rather large site to the latest Batmanjs/master, here were some of the things necessary to get it to work again. I should say, not just work, but work better. The Shopify team has made many improvements since the 13.1 branch we were on and it’s evident on the new site.

I’m not aware of an upgrade guide out there yet (since master hasn’t been minted into a release), so hopefully this can help some other people who are considering upgrading before that comes along.

The Bat Cave, Part 3: Views Changes

In the last blog post about Batman, we covered how bindings work…but what happens when views are added to the page?

As you can see below, when you add a subview to a view, an observer on the Batman.Set picks that up and fires @_addSubview(subview)

class Batman.View extends Batman.Object
  constructor: ->
    # ...
    @bindings = []
    @subviews = new Batman.Set

    @subviews.on 'itemsWereAdded', (newSubviews) =>
      # 1. woot, stuff has been added to my observed Set!
      @_addSubview(subview) for subview in newSubviews