Pivotal Labs

Alex Chaffee's blog



sub

edit Posted by Alex Chaffee on Tuesday October 02, 2007 at 03:06PM

Yellow Submarine

(Update -- version 0.3 released 2-Oct-07. Release notes are here.)

We use subversion for our source control. We love it. But we've noticed a few flaws, and a few weeks ago I decided I'd had enough and wrote a wrapper for it that fixes a few of the most glaring ones:

  • Externals get messed up pretty frequently. If you remove or rename an external, the old one gets left around on disk, and if you convert an external to a "real" directory or vice versa then the next update simply fails.
  • Externals are updated in series, not in parallel, meaning that if you have a lot of externals your updates can take an excruciatingly long time.
  • Externals are updated even if they're frozen to a specific revision number, which wastes even more time on update.
  • If you want a clean checkout -- say, for an automated build -- the only way to do it is to do a full checkout, even if 99% of the files are already there on disk.
  • The co command is not compatible with the convention of putting files under /trunk, requiring you to type out your whole repository URL followed by /foo/trunk foo
  • The name of the executable is hard to pronounce -- either "ess vee enn" or "seven", but nobody says "seven" except when they're saying "seven up", which is, I admit, a pretty good pun, but come on, how much cooler is it to say, "sub"?

The current version of sub fixes all of the above (except for converting directories to and from externals, and I'm going to make that work pretty soon).

Install with

sudo gem install sub

Help text is below the fold.

pong

edit Posted by Alex Chaffee on Thursday September 06, 2007 at 03:05AM

Oscillosocope Pong

ping is awesome, but it's a little simple-minded. I often find myself running several pings at a time, especially when debugging network configurations. And when you're watching ping run in several windows, as routers go up and down and packets spurt and congeal like blood in a trauma center, extra features spring naturally to mind...

Enter pong. It's a Ruby app I wrote that runs ping in the background and decorates the results, tracking statistics in realtime, refreshing the screen every 5 seconds. Here, I'll show you:

% pong localhost 192.168.1.240 192.168.1.1 google.com yahoo.com pivotalblabs.com

Last 10 seconds:
Mean            Missing         Host
   0.073 msec      0 (0.00%)    localhost (127.0.0.1)
   2.884 msec      0 (0.00%)    192.168.1.240 (192.168.1.240)
  25.745 msec      0 (0.00%)    192.168.1.1 (192.168.1.1)
  98.905 msec      0 (0.00%)    google.com (72.14.207.99)
  38.761 msec      0 (0.00%)    yahoo.com (66.94.234.13)
 113.418 msec      0 (0.00%)    pivotalblabs.com (72.9.100.34)

Last 60 seconds:
Mean            Missing         Host
   0.092 msec      0 (0.00%)    localhost (127.0.0.1)
   5.757 msec      0 (0.00%)    192.168.1.240 (192.168.1.240)
  24.198 msec      0 (0.00%)    192.168.1.1 (192.168.1.1)
  98.840 msec      1 (1.67%)    google.com (72.14.207.99)
  38.504 msec      0 (0.00%)    yahoo.com (66.94.234.13)
 110.687 msec      0 (0.00%)    pivotalblabs.com (72.9.100.34)

Entire run (97 sec):
Mean            Missing         Host
   0.088 msec      0 (0.00%)    localhost (127.0.0.1)
   5.716 msec      0 (0.00%)    192.168.1.240 (192.168.1.240)
  23.713 msec      1 (1.03%)    192.168.1.1 (192.168.1.1)
  99.261 msec      1 (1.03%)    google.com (72.14.207.99)
  35.403 msec      0 (0.00%)    yahoo.com (66.94.234.13)
 105.349 msec      4 (4.12%)    pivotalblabs.com (72.9.100.34)

I've packaged it up as a gem and put the source on RubyForge. Install it with

sudo gem install pong

and let me know what you think. Bug reports, feature requests, and (naturally) patches welcome. Currently it's only been tested on OS X and might work on other Unixes.

(Image of Edmond Lau's two-player analog oscilloscope Pong.)

Lovely Demeter, Meter Maid

edit Posted by Alex Chaffee on Sunday August 05, 2007 at 03:08PM

Wes and Parker pointed us to this article:

Misunderstanding the Law of Demeter by Dan Manges

which is a very nice discussion of the "law" (actually just a suggestion, but a very strong one) that encourages your objects, like small children, not to talk to strangers. Some people seem uneasy with the LoD since it requires them to refactor their objects to have proxy methods all over them. Instead of Paperboy calling customer.wallet.cash you have to put an extra method on Customer -- either cash (attribute delegation -- check out Forwardable in Rails btw) or pay (behavior delegation). But these proxy methods are not clutter, they're the essence of encapsulation. Do not fear encapsulation. Fear is the mind killer.

Anyway, Dan does a great job explaining this concept, until the very end of the article, when he totally chickens out.

The Joy Of Deleting Code

edit Posted by Alex Chaffee on Wednesday March 28, 2007 at 09:03PM

dog

Mark and I were just waxing poetic about how great it is to delete code, especially code you just wrote. We pity the attitude of people who think deleting code is somehow wrong -- they feel so guilty that they won't even delete it right off, they just comment it out, and then check it in... We came up with the following simile:

Writing code is circling your way around a solution, like a dog on the hunt. When you're done, the final solution is going to be a lot smaller than your original perimeter.

This reminds me (Alex) of my favorite quote about writing: "Murder your darlings," said by Sir Arthur Quiller-Couch... or was it..?

Ruby Puzzler

edit Posted by Alex Chaffee on Saturday March 24, 2007 at 05:58PM

puzzler I was just sitting around my living room listening to NPR, and heard the following Car Talk puzzler:

I want you to get a pencil and write down the numbers, 1 - 9, inclusive, and leave enough space between them. At your disposal you have one plus sign and two minus signs. You can insert those plus and minus signs wherever you want, to make the total come out to 100.

Naturally, I thought, "Gee, that would be tedious to solve it by hand. But it would be fun to write a Ruby program to solve it!" 9 minutes later I was sending the result (and the source code) to Car Talk Plaza.

So here's your challenge: can you write a program to solve this puzzle? And can you beat my time?

My solution is below the fold... don't click "more" until you've taken a stab at it yourself.

Paranoia

edit Posted by Alex Chaffee on Saturday February 24, 2007 at 03:32PM

Hoping to improve performance, we changed a query to use the :include condition like this:

    Project.find(id, :include => :stories)

and we noticed two things:

  1. ActiveRecord decided to turn that into a LEFT OUTER JOIN. Egads! This drastically slowed things down (although we didn't notice until several days later, when we ran a real load test with production data).
  2. acts_as_paranoid did not manage to stick it's little "and deleted_at = nil" phrase into the query. This meant that "deleted" stories showed up when they weren't supposed to.

So that's two gotchas for the price of one.

In email, Nick pointed out that the joining behavior is documented and appropriate ("otherwise if there is a nil association (eg a project without any stories) you wouldn't get a project back even though it exists!") and Miho rejoined that AR can be dangerous because it changes what looks like beautiful, elegant Ruby into nasty, ugly, hard-to-understand SQL under the hood.

less color is more color

edit Posted by Alex Chaffee on Saturday February 10, 2007 at 12:06AM

Ever do "less log/development.log" and see the following?

ESC[4;35;1mSQL (0.001084)ESC[0m ESC[0mSET character_set_results = utf8;ESC[0m
ESC[4;36;1mSQL (0.001792)ESC[0m ESC[0;1mSHOW TABLESESC[0m

Wouldn't it be nicer to see the colorization like when you're tailing the log with tail -f? Try using -R:

less -R log/development.log

Then you'll see

SQL (0.001084) SET character_set_results = utf8;
SQL (0.001792) SHOW TABLES

A bit more legible, eh wot old chaps?

Works on Mac and Cygwin too.

And -X makes it not clear the screen when you stop less, so you get to keep seeing what you were just seeing.

So that means you may want to put

alias less="less -RX"

or

export LESS="-RX"

in your .bash_profile.

Also, if you don't want the fancy colors at all, specify

ActiveRecord::Base.colorize_logging = false

in your environment file (e.g. test.rb.) We're doing that in our test.rb so we can more clearly read the output from our CruiseControl build.