jBoxer

I change the directions of small pieces of metal for a living.

Why eating sushi is a stressful experience for me

| Comments

I saw a Reddit thread asking if other people eat parts of their meal in proportion to one another so that all the food is gone at the same time.

I definitely do this, and it’s usualy fine, but I have a real problem with sushi/maki. If I’m eating multiple rolls, I always need to come up with a sequence to eat them in that’s as well-distributed as possible.

Of course, this is easy if all my rolls have the same number of pieces. For example, if I get a Spicy Tuna (S) roll and a Philadelphia (P) roll, and they each have 6 pieces, my order will be:

P S P S P S P S P S P S

Easy. (and to note: I eat the Philadelphia before the Spicy Tuna because I like Spicy Tuna more and I want it to be the last taste in my mouth).

Now, let’s say I order a Spider (I, cuz S and P are taken) roll and a Caterpillar (C) roll. A Spider roll usually has 4 pieces, and a Caterpillar roll usually has 8. So, I’ll do this:

C C I C C I C C I C C I

Still easy.

Now, let’s say I pair the Spicy Tuna roll (S, 6 pieces) with the Caterpillar roll (C, 8 pieces). I do this:

C S C S C S C -- C S C S C S C

That -- in there is meaningless; it’s just to help your eye break it up better. In short, I’m dividing up my eating experience into two halves, each of which start and end with a Caterpillar roll piece, and then alternate between that and the Spicy Tuna.

Trickier.

Enter the chaos-inducing Spicy Scallop roll (Jesus Christ why does all sushi start with the same letters? This is A I guess). At my favorite sushi restaurant, it has 5 pieces. Fuck.

If I’m eating it with a Spicy Tuna (S, 6) roll, it’s not so bad:

S A S A S A S A S A S

If I’m eating it with a Caterpillar (C, 8) roll…

C A C A C -- C A C -- C A C A C

Now my eating experience has two halves and a short halftime show in the middle. Maybe I’ll eat some ginger during that time as well. Fuck that, straight ginger is nasty.

So yeah, this adds a lot of stress to my sushi-eating experience. But it doesn’t end there. What if I’m extra hungry, and get three rolls; Spicy Tuna (S, 6), Caterpillar (C, 8), and Spicy Scallop (A, 5)? Once I stop hyperventilating, I’ll do it like this:

S C A C S -- C A C S A S C A C -- S C A C S

For the record, I do understand how fucked up this is, but this brilliant three-course-meal-within-a-one-course-meal means I never eat the same piece twice in a row, and I get the satisfaction of eating a palindrome.

It can get worse than this. Sometimes, I want to get four or five rolls and split them with my girlfriend. Sometimes I know I’m with someone who will want to trade a piece, so I have to factor in a group of 1.

I’ll spare you these horrors, since I think you get the idea. But if you’re ever out eating sushi with me, and I’m sitting there staring at my untouched plate with an intense look on my face while everyone else is half done, now you know why.

Converting to the new RSpec 2.11 expectation syntax

| Comments

RSpec 2.11 was released a few days ago. The biggest change is a brand new expectation syntax by Myron Marston.

Now, instead of writing this:

Old expectation syntax
1
2
foo.should eq(bar)
foo.should_not eq(bar)

You can write this

New expectation syntax
1
2
expect(foo).to eq(bar)
expect(foo).not_to eq(bar)

Myron’s blog post does a fantastic job explaining why this is better. To summarize:

  1. RSpec does not own every object in the system, so it cannot add the should and should_not methods to every object. This can lead to some really confusing errors. Using expect works around this.
  2. Block expectations already used the expect syntax out of necessity. The inconsistent syntax made it harder to read specs that used both. Using expect for normal expectations unifies the syntax, making these specs much more readable.

What follows is a step-by-step guide to convert all your specs from the old syntax to the new one as quickly as possible.

Change all equality operator matchers

The new expectation syntax does not support foo.should == bar. You need to do expect(foo).to eq(bar). So, go through all your specs and make this change.

You can use this regular expression:

Regular expressions for replacing == with eq()
1
2
3
4
5
6
7
# Note that these both start with a leading space. Don't forget them, or they won't work.

# Find
/ == (.*)$/

# Replace  
/ eq($1)/

For global find/replace stuff, I prefer to open and editor and click “Replace” over and over. It’s slower, but I don’t have to track down mistakes afterwards, and I get to improve my regex as I go. Feel free to do it however you want, but make sure to check your diff afterwards.

Once you’re done, re-run your specs and make sure everything is still passing. Note that we haven’t yet changed should to expect, so everything should be passing.

Change other unsupported operator matchers

These should be rare enough that you don’t need a regex. If you do, write it and send it to me, and I’ll include it in here and give you credit.

Go through all your specs and make these changes:

Unsupported operator matcher replacements
1
2
3
4
5
6
7
8
9
10
11
# Regex matching
"a string".should =~ /a str[iou]ng/ # Old, bad.
"a string".should match(/a str[iou]ng/) # New, good.

# Matching array contents while ignoring order
[1, 2, 3].should =~ [2, 3, 1] # Old, bad.
[1, 2, 3].should match_array([2, 3, 1]) # New, good.

# Comparison matchers (do this with ALL matchers: <, <=, >, >=)
foo.should < 10 # Old, very bad. You should never have been using this.
foo.should be < 10 # New, good

Re-run your specs and make sure everything is still passing.

Disallow “should” from your specs

Open your spec/spec_helper.rb file and add the following lines to your configuration block:

spec/spec_helper.rb
1
2
3
4
5
6
7
8
9
10
RSpec.configure do |config|
# .. other stuff

  # Add all three of these lines:
  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

# .. other stuff
end

This will stop RSpec from adding should to all objects. Make sure you add all three lines; I didn’t realize it was within a block at first, and got errors.

If you run your specs now, pretty much everything should fail.

Replace should and should_not with expect

This is the most tedious part. Luckily, I came up with a regex that works for both should and should_not. Here it is:

Regular expressions for replacing should/should_not with expect
1
2
3
4
5
# Find
/^(\s+)(.*(?=.should))\.should(_)?(not)? (.*)$/

# Replace
/$1expect($2).$4$3to $5/

One caveat: this will not work for expectations that aren’t on their own line. Example (using Capybara)

Working and non-working examples for regex
1
2
3
4
5
6
7
# Regex WON'T find/replace properly
within('#header') { page.should have_content('About') }

# Regex WILL find/replace properly
within '#header' do
  page.should have_content('About')
end

The first example won’t work, because the expectation comes after within('#header') {. The second will work, because the expectation is on its own line.

So, like I said above, don’t just do one “Replace All”; click the “Replace” button in your editor over and over, so you can spot these broken cases and fix them manually.

I tried for awhile to fix these broken cases, but I’m pretty sure it’s not possible via regex. If someone can prove me wrong, I’d love to update this guide and give you credit.

After doing this in all your specs, re-run them. Everything should pass. If not, comment, and I can try to help you figure out what’s up.

Changing a Rails 3 project name

| Comments

I’ve had to change Rails 3 project names a few times now. It’s too bad there’s no rake command for it. Here’s the next best thing: a step-by-step guide.

For the sake of this example, let’s say I’m changing my name name from “Teach” to “Learn”.

Update your app’s module name

In /config/application.rb, change the name of the module:

/config/application.rb
1
2
3
4
5
module Learn # Used to be `module Teach`
  class Application < Rails::Application
    # ...
  end
end

Update references to your app’s module name

Your app’s module name should appear in /config.ru:

/config.ru
1
2
3
4
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Learn::Application # Used to be `run Teach::Application`

And in /Rakefile:

/Rakefile
1
2
3
4
5
6
7
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

Learn::Application.load_tasks # Used to be `Teach::Application.load_tasks`

Your app’s module name should also appear in a bunch of files under the /config directory. It should appear in /config/environments.rb.

/config/environments.rb
1
2
# Initialize the rails application
Learn::Application.initialize! # Used to be `Teach::Application.initialize!`

It should also appear in all the environment-specific configurations in /config/environments/*.rb (which should be development.rb, production.rb, test.rb, and any other environments you have configured). Change them all:

/config/environments/*.rb
1
2
3
4
Learn::Application.configure do # Used to be `Teach::Application.configure do`
  # Settings specified here will take precedence over those in config/application.rb
  # ...
end

And in your initializers (under /config/initializers/). At the very least, /config/initializers/secret_token.rb and /config/initializers/session_store.rb should have it:

/config/initializers/secret_token.rb
1
2
3
4
5
6
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Learn::Application.config.secret_token = 'garbagestring'
# Used to start with `Teach::Application`
/config/initializers/session_store.rb
1
2
3
4
5
6
7
8
9
Learn::Application.config.session_store :cookie_store, key: '_learn_session'

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Learn::Application.config.session_store :active_record_store

# For the sake of cleanliness, I changed it from `Teach::Application` in both the actual
# line of code and the comment. Also, `:key` used to be '_teach_session'.

And in your /config/routes.rb file:

/config/routes.rb
1
2
3
Learn::Application.routes.draw do # Used to be Teach::Application.routes.draw
  # Routes in here
end

Finally, for consistency’s sake, if the names of your databases include your app name, you should update those in /config/database.yml

/config/database.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
development:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: learn_development # Used to be teach_development
  username: root
  password:

test:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: learn_test # Used to be teach_test
  username: root
  password:

production:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: learn_production # Used to be teach_production
  username: root
  password:

Search your app and lib folders

grep through your /app and /lib folders to find any mentions of your project name and change them. This might be a little tedious if you have a name that conflicts with a bunch of Ruby/Rails stuff (like “def” or something stupid like that), but you only have to do it once.

Done!

That’s it! Now you have a renamed Rails 3 app.

Note: I did this on Rails 3.2.1. It’s possible some things will be different on other versions.

BostInnovation’s Seth Priebatsch Article is Childish Garbage

| Comments

Disclaimer: I was SCVNGR’s lead iOS developer for almost two years. I started a new job at GitHub last month. This is neither a critique nor a defense of the actions or words of Seth Priebatsch or SCVNGR.

Today, BostInnovation published an article called Seth Priebatsch Thinks Everyone at BostInno is Painfully Stupid… Really?. In it, they publish an internal SCVNGR email in which Seth insults them, then spend the rest of the article defending themselves from his insults and offering him advice on how to have fun and run a company.

Like most media outlets, I have mixed feelings about BostInnovation. The article in question, however, is childish garbage.

The are some points to be made here that anyone who is techy enough to read BostInnovation knows. There’s no way to prove this email is real. There’s no way to prove that the “leaker” didn’t tweak it. But those aren’t the important part.

The important part is, this was an internal email. Were it not for BostInnovation, under 100 people would’ve read it, all of whom work for SCVNGR. This email was no threat to BostInnovation’s readership. This is reminiscent of elementary school kids intercepting a passed note and reading it out loud to all their friends.

If the focus of this article was “Seth is lying to the media and investors,” that would be a different story (and would require significantly more evidence). I would still be a bit off-put by the publishing of an internal email in a private company, but at least that would be news worth reading. Instead, the focus is “CEO of company thinks we’re dumb, so here’s why he’s weird and mean.” If I were an advertiser on BostInnovation, I would be pretty upset with this.

Bash’s PS1 Syntax: The Inspiration for Brainfuck?

| Comments

I just spent way too much time struggling to get my Bash PS1 variable working right. Originally, it looked like this (parse_git_branch is a Bash function I have defined elsewhere):

Old PS1
1
PS1="\w\e[35m\$(parse_git_branch)\e[m > "

Now, it looks like this:

New PS1
1
PS1="\w\[\e[35m\]\$(parse_git_branch)\[\e[m\] > "

The difference? I wasn’t escaping my color codes correctly, which was causing Terminal to wrap long commands onto the beginning of the same line.

Let me break down Bash’s color code syntax, because it makes me so angry. A minimal Bash color code looks like this:

Minimal Bash color code
1
\e[1;30m

\e[ means “here comes a color code” I guess.

1 means “make it bold”. If you don’t want bold, leave it out.

; means “I’m finished telling you that this is bold”. If you don’t want bold, or if you want default-colored text (explained below), leave it out.

30 means “dark gray”. Here’s an exhaustive list of valid numbers (no number means default color):

  • 30 = dark gray
  • 31 = red
  • 32 = green
  • 33 = yellow
  • 34 = blue
  • 35 = purple
  • 36 = turquoise
  • 37 = light gray

0-29 don’t do anything (at least in Terminal.app on OS X 10.7.2). No idea why they start at 30.

m means “my color code is over”.

If you match that format, all subsequent characters will be that color (until you define another color code).

But that’s not all! This sequence is escaped incorrectly. If you have it in your PS1, Terminal will look correct on startup, but if you type a long command that wraps past the first line, Terminal will wrap it back to the beginning of the line you’re on and start overwriting characters.

I bet you think the fix is to match the open square bracket with a closed one, right? If so, give yourself a half pat on the back, then punch yourself in the face. Here’s how to escape it correctly.

How to escape a Bash color code
1
2
\e[1;30m     # Wrong
\[\e[1:30m\] # Right

You need to close match the open bracket (with an escaped close bracket), but also add another open (escaped) bracket to the front, also with no closer.

Anyone wanna educate me on the reason for all this madness? Right now, it just feels like some dude thought regular expression and strftime syntax were too verbose.

Using acts_as_list in a polymorphic scope

| Comments

If you’re using acts_as_list in a polymorphic scope, you need to define the scope a little bit differently to make everything work right.

Here’s the non-polymorphic example from acts_as_list’s README:

acts_as_list in a normal (non-polymorphic) scope
1
2
3
4
class TodoItem < ActiveRecord::Base
  belongs_to :todo_list
  acts_as_list scope: :todo_list # Note the single-item scope
end

We pass :todo_list as the scope (which acts_as_list converts to the todo_list_id column).

Now, let’s say we’re making a polymorphic Picture model (like in the Polymorphic Associations section of the Ruby on Rails Guides), and we want pictures to be sortable and reorderable. Here’s the right way to do it:

acts_as_list in a polymorphic scope (the RIGHT way)
1
2
3
4
class Picture < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
  acts_as_list scope: [:imageable_id, :imageable_type]
end

My pre-ARC Objective-C memory management conventions

| Comments

iOS 5 is coming soon, and introduces ARC. ARC will make Objective-C memory management significantly simpler. But, it will be a long time before iOS 5 is ubiquitous, and I’m not sold on the subset of ARC that will be available for iOS 4. So, in the meantime, I thought people might benefit from seeing the conventions I use to keep Objective-C memory management simple. Most iOS developers probably already follow something close to this, but it doesn’t hurt to have it written out.

If you follow these five simple rules, you should pretty much never get a memory leak or a crash from over-releasing.


1. Always declare @properties for your object instance variables

If you’re putting an instance variable on a class and it’s an object, declare a property for it.

Moving to Octopress

| Comments

I’m now moving all my stuff from Media Temple and Tumblr to here. All posts before this one are reposts.

My tips for an awesome WWDC

| Comments

I’ve seen a bunch of people who just got back from WWDC posting advice on how to have the best time possible. I figured I should do the same thing. Here are my tips.

Don’t get in the keynote line early

Even if you want to sit near the front, you don’t need to get in line until around 8:30am. It’s really easy to just run and push past all the submissive nerds and get an awesome seat.

Live-blog the keynote

People who aren’t at the keynote would much rather read you repeating Steve Jobs’ announcements sentence-by-sentence on Twitter than watch a live feed with pictures. Also, other people in the audience who are following you will love reliving the moment when they look through their tweets later on.

Complain about the food

You paid a lot of money for tickets, which entitles you to demand customized gourmet meals. Food should be the main concern at any tech conference, and if you aren’t absolutely overjoyed by what you’re putting in your mouth, you aren’t getting your money’s worth.

Don’t silence your phone before a session begins

I know they ask you to before every session (and you should roll your eyes and say “do they have to say this every time?” when they do), but they’re really just forced to say that by law. In reality, all the speakers helped make these devices, and it’ll make them proud to see you using them. In fact, feel free to quietly answer your phone right in the middle of a talk. No one will notice.

Code during sessions

There are very few places in the world where you will have the opportunity to write code. A conference that you paid $1600 to attend is one of these places, and you should take advantage of that. Besides, you can just watch the session videos later.

Don’t go to any parties afterwards

You’re probably better at programming than the other attendees. Meeting them is pointless, and won’t be fun (and all the parties charge lots of money for alcohol, especially at Apple’s beer bash). Also, your hotel room is another one of the aforementioned few places in the world where you can code, so you should stay there and do that instead.

These tips will guarantee you a quality WWDC 2012. Also, don’t read any other WWDC tip posts, they’re probably trying to troll you.

The misguided priorities of Twitter

| Comments

Today, Twitter announced (with some awesome spin) that they would hamstring the direct message capabilities of all 3rd-party Twitter apps.

It’s been clear for awhile that one of Twitter’s monetization strategies is to force everyone to use their mobile apps over those of third-parties. This will let them show promoted trending topics in the newly-neutered Dickbar to all mobile users. I understand that Twitter needs to find a way to make money, but this direction strikes me as extremely misguided.

I believe this lock-in strategy will never create enough revenue to cover a non-trivial portion of their operating costs (never mind the $10 billion they turned down from Google). In the meantime, it will alienate the developers who were once the lifeblood of the Twitter ecosystem. Without these developers, the 3rd party apps that Twitter does want (cool aggregations, visualizations, etc.) will not be built, and new developer-fueled uses of the service will not be able to thrive.

It seems to me that the folks making business decisions at Twitter are severely underestimating the importance of certain parts of the community, and/or severely overestimating the potential revenue from their own mobile apps.