This site provides the following access keys:

Brandan Lennox's

Articles (Page 4)

GoDaddy Scumbaggery

Many moons ago, I registered a domain at GoDaddy. I knew how to navigate their shit-tastic UI from my client work, and they were at least marginally less reprehensible back then. Since I planned to use the domain for a while, I stored my credit card information and turned on auto-renewal.

Times change. I no longer need the domain, and GoDaddy sucks. A few months ago, they started sending me auto-renewal reminders and warning me that the credit card on file had expired. I knew that, and I didn’t care about the domain, so I just ignored the e-mails figuring that the charge would fail and the domain would be released. I’m nothing if not passive-aggressive.

Today, while unsubscribing from unwanted e-blasts collected in my spam folder, I saw a notice for a successful auto-renewal of that domain. I never updated my card’s expiration date at GoDaddy. I thought they might have been lying or joking, but the charge showed up on my account. Shocking, no?

I have to assume that they guessed the new expiration date of my card. It seems like my expiration dates advance three years at a time, so maybe that’s the first thing they try with expired cards. I don’t know if this is generally accepted practice, but it disgusted me.

My time is worth more than the $12 charge, so I’m not going to dispute it. I did release the domain and remove my payment information, and if I could figure out how, I’d cancel my account altogether.

Fuck those guys.

“To iterate is human…”

“…to recurse, divine.”

That’s one of maybe five of these fifty programming quotes I can recall at will. I actually used it today. Super proud about this one!

At work, our thing uses a tree structure with a Rails model like this:

class Node
  has_one :parent, :class_name => 'Node'
  has_many :children, :class_name => 'Node', :foreign_key => :parent_id
end

We needed the “path” from any given node back to the root of the tree. It was originally implemented as a named scope and an instance method that called that scope:

scope :path, lambda { |id| 
  {
    :select => 'parent.*',
    :joins => ', nodes AS parent',
    :conditions => ['nodes.left BETWEEN parent.left AND parent.right AND nodes.id = ?', id],
    :order => 'parent.left'
  }
}

def path
  self.class.path(id)
end

It’s was performing terribly on large data sets. Not only was the query performance bad, but we were only ever using the return value of the named scope as an array. There was no need for all the overhead of a named scope. We determined that it would actually be faster to hit the database n times for a node at depth n than to join all the ancestors in one query.

My first thought was to collect the node’s parents in a loop:

def path
  node = self
  parents = [node]
  while parent = node.parent
    parents.unshift parent
    node = parent
  end
  parents
end

It worked. Tests passed. Performance was astronomically better (down to 1ms from 270,000ms). I almost checked it in, but I hesitated. I heard the faint voice of L. Peter Deutsch, snickering at me in that way he almost certainly must.1 “Loops?” he said. “Gfaw.”

In about two minutes, I came up with this:

def path
  parent.path << self rescue [self]
end

Shit! I mean, the syntax might be a little wonky if you don’t read Ruby, but that’s magic. From a named scope with a lambda doing some kind of SQL query that stumped three professional programmers2 to one beautiful tail-recursive line. I’m patting myself on the back pretty hard!

Footnotes

  1. If your quip about programming made it into a well-known list, you probably snicker at bad programmers.
  2. I still don’t know why we were filtering by left and right values and an ID.

My Pet Theory on Popular Music

Kurt Andersen wrote a great article at Vanity Fair detailing how American culture hasn’t changed in the past two decades. He goes into a lot of detail, covering art, fashion, industrial design, architecture, but I’ve noticed this specifically about music, or at least popular music. No genre has dominated music — and consequently style — since grunge and gangster rap in the early 90s.

Some Loose Reasoning

Since the gramophone became the dominant commercial recording format in the early 1900s, popular musical styles have come and gone very nearly with each passing decade:

  • 1920–40: swing dancing and big-band jazz groups, like Lawrence Welk, Duke Ellington, and Count Basie
  • 1940–50: the decline of swing, the rise of bebop and cool jazz (Bird, Diz, Miles)
  • 1950–60: rock-n-roll (Elvis, Chuck Berry, Jerry Lee Lewis)
  • 1960–70: hippie and counter-culture rock (The Beatles, The Grateful Dead, Dylan)
  • 1970–80: disco (Village People, The Bee Gees, Kool and the Gang)
  • 1980–90: new wave and hair metal (The Cure, Aerosmith)
  • 1990–95: grunge and gangster rap (Nirvana, Dr. Dre)
  • 1995–present: ?

These are generalizations. Yes, the 70s produced more music than just disco. Yes, rap was around long before Dr. Dre. Yes, pop-punk had a good run in the late 90s.

But I’m looking at Top 40 cultural phenomena. When you think 70s music, you think disco. When you think 90s music (and you’re white), you think grunge. When you think 00s music, you think…of nothing in particular.

What happened?

Further Analysis

When I bring this up, a lot of people tell me that “pop” is the defining genre of the 00s, but that’s some kind of weird recursion. “Pop music” is exactly that: popular music. We only call Ke$ha “pop” because she doesn’t evoke a better description. Other than production quality and vernacular, how different is a Lady Gaga song from a Madonna song from a Gloria Gaynor song? “Pop” is too generic to incite a movement. It’s just furniture.

What else? R&B hasn’t changed. Rock hasn’t changed. Country hasn’t changed.1 Electronic hasn’t changed. And I can’t think of a single genre in Top 40 music today that wasn’t around twenty years ago.

Can you imagine Nickelback on MTV in 1992? Of course. Can you imagine Soundgarden on American Bandstand in 1972? Not one bit.

Theory

Andersen makes several strong arguments in his piece, this being my favorite:

In some large measure, I think, it’s an unconscious collective reaction to all the profound nonstop newness we’re experiencing on the tech and geopolitical and economic fronts. People have a limited capacity to embrace flux and strangeness and dissatisfaction, and right now we’re maxed out. So as the Web and artificially intelligent smartphones and the rise of China and 9/11 and the winners-take-all American economy and the Great Recession disrupt and transform our lives and hopes and dreams, we are clinging as never before to the familiar in matters of style and culture.

As it relates to music, technology has been even more disruptive. Look at this chart from Business Insider:

Graph depicting the decline of revenues in the music industry from 1973–2009

Revenues dropped precipitously around the turn of the century, inarguably because of Napster and affordable high-speed broadband. But Napster was more than just a means of mindlessly stealing songs: it democratized the process of discovering music.

Of the people I know who regularly pay for music — whether it’s from iTunes, Amazon, record stores, or live shows — none of them listens to FM radio. There are so many more sources of music discovery now. You can:

  • shuffle your iPod,
  • subscribe to a podcast like All Songs Considered,
  • browse sites like PureVolume and SoundCloud,
  • listen to playlist generators like Pandora and last.fm,
  • watch independently produced music videos on YouTube, or
  • exist on a social network.

We have such sophisticated artificial and human recommendation engines. Why would you listen to a generic radio station that’s required by contract to rotate the same nonsense day in and day out?

The early 90s were the last stand for Clear Channel radio and big music. Back then, if they decided to make something huge, they could push it to every radio station and MTV affiliate in Western culture. Now our attention is too divided. They can push the songs, but the people who hear them aren’t the trendsetters. Maybe they’ll buy an album or a ticket, or most likely a single, but there’s just no culture behind the music anymore.

Onward

Plenty of artists are still releasing great music. I’m not arguing against that. Some of it even goes mainstream. I just don’t think that we’ll ever again witness a sea change in popular music like we did repeatedly throughout the 20th century, and we’re no worse for it.

Footnotes

Code Hygiene

The second law of software thermodynamics:

Your code tends toward higher entropy. Brandan Lennox, 2012

The Problem

The more code we write, the harder it is to tell useful code from useless code, and the longer it takes to turn the latter into the former.

The Amalgam

These examples all come from our Rails project at work.

  1. For three and a half years, the code, which isn’t public or user-accessible, still contained the default README and an empty doc subdirectory.
  2. We use Workling for background jobs. Mainline development on Workling stopped in 2009, and it’s no longer compatible with Rails 3.1. Same with Machinist.1 Same with Spork.2 Our adoption of a project is a death sentence.
  3. Until recently, we had four separate subdirectories housing executable scripts: bin, script, runners, and utils. Only script is Rails-sanctioned (and necessary).
  4. We have to execute asset precompilation in a custom Rails environment — i.e., we can’t use the production environment like you would expect. I don’t know why. In addition to that, one co-worker recently created his own environment for development. I guess he wasn’t happy with development or production, so he combined the two. So now we have 66% more execution environments than a normal Rails project.3
  5. Speaking of environments, we have a custom initializer for our test environment that adds 10,000 to the current autoincrement value for the id column of certain tables. That’s how we fixed a conflict between Postgres, fixtures, and Machinist. We’ve switched from Machinist to FactoryGirl, but we left that initializer in place because insert reason here.

The Stink

It’s not just a matter of refactoring. I find a lot of code that isn’t even executed anymore. It’s just taking up disk space and attention, but you can’t know that until you spend the time to figure out what it does.

And it’s not just a matter of compulsion. The problems I listed above really do hurt us:

  1. Okay, maybe not this first one, but…
  2. We missed a release date because of a bug in Workling that we didn’t find until the very end of the test cycle. By then, we didn’t have time to replace Workling with a current tool, so we hacked around the bug and released. Is that going to bite us once it’s out in the field?
  3. If I want to create a new executable script, which directory am I supposed to put it in? What’s the difference between a runner, a script, and a util? Who’s executing these scripts, and do they have a good reason for this arbitrary directory layout? Why am I having to make this decision?
  4. Why did someone have to create a precompile environment? How is it different from production? How do we know if a future version of Rails fixes whatever problem we had with asset precompilation?
  5. We spent so many hours fixing problems with Machinist that were never going to be fixed by its developer. But FactoryGirl seems to work fine. Do we still need to futz with these autoincrement values? It slows down our tests and represents a significant break from normal development. Is something else depending on that behavior, or can we get rid of it?

The Cleansing

I need to learn to balance my compulsion for pristine code with my requirement to produce. It wasn’t a big deal when I worked by myself because the projects were small, short-lived, and completely owned by me. Now, it’s not just a poor use of time, but it creates tension between you and me if I’m always rewriting your code without good reason.

In related news, I’m going to start writing a lot more code for myself :-)

Footnotes

  1. Stuck in 2.0.0.beta2 since July 2010.
  2. Spork 0.9.0 will be compatible with Rails 3.1, but 0.9.0.rc9 was released in June 2011 and somehow still hasn’t made it to final. The last commit on Github was November 8, 2011. Curiously, the only reason I know about Spork was a flurry of activity early last fall. What happened to it?
  3. Not to mention the selenium environment I recently removed. We haven’t run Selenium directly against our Rails app in at least the two years that I’ve been working there.

Simple Pleasures

iOS 5 has delivered my most anticipated feature: custom text tones. I can finally hear the Super Mario Kart coin ding every time I get a message:

I found a lot of low-quality MP3s of this sound (and the coin sound from Super Mario Bros., which is different). They all sucked. Thanks to BSNES and Audio Hijack Pro, I created a pristine copy. You can download the ringtone file in MP3 or AAC. 1

Footnotes

  1. iTunes requires the .m4r extension, but it’s plain old AAC.

Hiding Users on OS X Lion's Login Screen

I recently changed my workflow at my job so that all my source lives on my laptop, rather than on an NFS-mounted disk on another server. I simply reversed the flow, so now, that server points to an NFS share on my laptop. It was shockingly easy to set all this up on Lion, but since NFS relies on numeric user IDs rather than user names, I was having problems with permissions. My user over there didn’t have the same numeric ID as my user over here.

My solution was to create a new user on my laptop with the correct numeric ID. Google revealed dscl, OS X’s analog of useradd on other Unix systems:

sudo dscl . -create /Users/brandanl ...

This worked like a charm — except this user was now showing up on the login screen, and I never intend to log in as him. Turns out, I just needed to unset his shell:

sudo dscl . -append /Users/brandanl UserShell /usr/bin/false

Cruft decrufted.

TextMate-style Commenting in BBEdit

Update on : As of BBEdit 10.1.1, this has been fixed.

Since July, I’ve been moving from my beloved-but-abandoned TextMate to BBEdit. It’s good. I like BBEdit. I like the feel, I like knowing that bugs will be fixed and new OS X APIs will be implemented…

But I miss the way TextMate comments out the current line when there’s no selection. Seems trivial, but I use it all the time. Kerri wrote a script to do this, but it wouldn’t block comment a selection, so I needed to remember two separate keystrokes: one when there was a selection and one when there wasn’t.

Instead, I changed the original script to act as a Menu Script and attached it to the “Text > Un/Comment Selection” menu item. If there’s a selection, it passes control back to BBEdit. If there’s not, it works its magic.1

The menu script is on Gist. Save that file as ~/Library/Application Support/BBEdit/Menu Scripts/Text•Un/Comment Selection2, and you’re off to the races.

Update on : Looks like Allan really is still working on TextMate 2. I’m excited to see what he’s done, but I doubt I’ll go back. Who’s to say it won’t be another five years until the next major update?

Footnotes

  1. It’s not exactly the same. TextMate places the comment delimiter in front of the first non-whitespace character on the line. This script places it at the beginning of the line.
  2. Finder will allow you to save a file with a slash in the name. Thanks to Patrick at Bare Bones for helping me figure that out.

Muzak

I created this video one night last year as an homage to some of my favorite music and musicians. I originally uploaded it to Facebook, but I feel like it belongs here (now that I pay so little mind to Facebook).

Thoughts on Copyright

I felt a strong visceral reaction when I first read Andy Baio’s Kind of Screwed. That was several weeks ago, but reading today about the Thomas Hawk fiasco got me riled up again.

Not being a copyright holder of any sort, I side with Baio, even after several IP lawyers opined that the album art would’ve almost certainly been deemed derivative in court. It’s entirely possible that Baio was in violation of copyright law. My problem is with the law itself.

My Two Complaints

First and most concretely, it seems impossible that Baio inflicted $150,000 in damages to Maisel. Kind of Bloop sells for $5. If Maisel were to receive $0.50 for each sold copy — which seems high; is the cover art one-tenth the value of the entire album? — that means Baio would’ve sold 300,000 copies. I simply can’t imagine such an obscure, experimental project selling anywhere near that well. Hell, Kind of Blue is the best-selling jazz album in history, and it just cleared 4 million copies after selling for forty-nine years. And how many sales did Kind of Blue forfeit to its lo-fi counterpart? Not many, I’ll wager.

But I’ll put my speculations aside. This is really what galls me: Jay Maisel took that photograph in 1959, and he’s been receiving royalties as the copyright holder ever since. Maisel is still being paid, litigiously or otherwise, for a piece of work that he created over five decades ago.

Maybe this irks me so much because I’m a developer. Software just doesn’t age well. My work from five years ago is essentially valueless. Windows XP? That’s ten years old! Its installation discs should be in museums! Can you imagine using any piece of current software in 2060? Ludicrous.

I’m not discounting the artistic value of Maisel’s photograph. It’s iconic, historic. I don’t believe, though, that it’s worth $32,500 in 2011.

My Solution

Oh, don’t be silly! I don’t have a solution. It’s clear that we as a society don’t know how to apply current copyright and patent law to new technology. There’s no way we can continue awarding software patents with lifetimes measured in decades (cf. Lodsys). We’ll bury innovation in the very system that means to foster it.

Given that, why does it make any more sense to grant rights on a photograph for so obscenely long? To promote creativity? Maybe Andy Baio could have or should have designed a different cover for Kind of Bloop. But why? The design was pitch-perfect: a bit tongue-in-cheek but still artful, just like all the music on the album.

At any rate, I purchased a copy for myself. It’s weird.

All art is theft.