A New York City farewell eating tour

Posting this mostly for my own records.

Next week, I’m moving away from New York. Starting with a pizza tour a few weeks ago, I’m trying to cram in some quality NYC meals in my last stretch as a New Yorker. Some of these are classic places, some are on the list for sentimental reasons. Here’s a summary of where I’ve been in the past few weeks, along with a few places slotted for my remaining 10 days:

First, the pizza joints:

Etc:

  • Bagels: have been hitting my local, but would like to get a last trip to The Bagel Hole
  • Court Pastry Shop, for the spumoni and maybe a lobster tail
  • White sauce hot sauce – probably won’t make it to my favorite Halal cart (near Queens College), but trying to patronize all my neighborhood stands
  • Some quality pastrami – probably Pastrami Queen, which is near my place and is ridiculous
  • A last slice of the weirdly delicious cheesecake at my favorite diner

Custom version-based cache busting for WordPress CSS/JS assets

WordPress appends a query var like ?ver=4.2.1 to CSS/JS URIs when building <link> and <script> tags. When WP’s version changes (eg, from 4.2.1 to 4.2.2), the query var changes too, causing browsers to bypass their cached assets and forcing a fresh version to be requested from the server. This works well for core assets, because they generally don’t change between WP releases. But for assets loaded by plugins and themes – which don’t always provide their own ver string when enqueuing their scripts and styles – it’s not a perfect system, since browser caches will only be busted when WordPress core is updated.

I built a small filter for the CUNY Academic Commons that works around the problem by appending our custom CAC_VERSION string to all ver query vars. This ensures that users will get fresh assets after each CAC release, whether or not that release includes a WP update.

Note that this code is pretty aggressive: it busts all CSS/JS caches on every release. You could use the $handle argument to do something more fine-grained. Note also that this technique doesn’t work equally well for all caching setups; see this post for an alternative strategy, based only on filename. Proceed at your own risk.

One of the suckers

At the beginning of the 4.2 dev cycle, I was made a permanent committer for WordPress. (Cool!) Here’s how Andrew Nacin summed up the promotion:

Suckers

Suckers

Any maintainer of a large free software project will recognize the aptness of the “suckers” comment. I’ve spent more than five years as a leader on the BuddyPress project, and during that time I’ve developed a devotion to that project that sometimes feels like more like servitude than volunteerism. I feel a personal responsibility to the users of BuddyPress, which manifests itself as a pang of guilt about every bug, every missing feature, every unsatisfied customer. This guilt is part (not all, but not an insignificant portion) of what keeps me committed to the project. The same guilt sometimes makes me feel like a sucker.

With BuddyPress, the “sucker” aspects have been consistently counterbalanced by (a) the belief that my work is having a broad positive impact, and (b) the positive effect that contribution has on my reputation and my marketability. Point (b) is one that I’ve blathered on about on multiple occasions. My ability to make money as a consultant is directly tied to the reputation that I’ve earned doing free software work.

Since I started investing lots of energy into WordPress itself about nine months ago, I’ve been forced to reassess the “reputation cycle” somewhat. WordPress powers tens of millions of sites, as compared to BuddyPress’s tens of thousands. By this metric, the free software work I’ve done since September has had a far wider impact than any work before then.

You’d think that this increased impact would translate directly into a corresponding increase in reputation. Yet it hasn’t, at least not if you measure reputation by job offers. This time last year, I was turning away probably three or four freelance gigs per week, and probably one or two full-time jobs per month. I don’t get a fifth of that amount today.

This is not to complain – I am doing just fine, thankyouverymuch. But it’s worth thinking about the possible reasons why increased impact and productivity don’t always translate to more work. I think there are two big ones.

First: The further down you get in the technology stack, the more it feels like plumbing. I’ve built a number of major user-facing features for BuddyPress over the years, the kind of things someone might point to and say, “Boone built that”. My work on WordPress has been a lot less visible, and thus a lot harder to brag about. This is the truth in Nacin’s “suckers” comment. No one praises the plumber when the toilet flushes properly, but boy do people complain when it does not.

Second: I joined the WP core team around the time I stopped using Twitter. The time I used to waste looking at Twitter is time I now sink into doing meaningful work on projects like WordPress, which is to say that I’m more productive now than I used to be. But I’m talking less, and talking less about myself. If the Boone brand is in decline, it’s a publicity problem, not a quality problem. This is another side of the “sucker” coin: the greater the percentage of your time you devote to being productive, the less time you have to talk about how productive you are.

The characters in the Cheers opening: A critical analysis

One of the great TV memories of my childhood is the Cheers opening sequence. I’m a great lover of TV theme songs, and I remember Cheers being one of my favorites. I’ve been rewatching Cheers, and the show is still great, but I find the old-timey images used during the opening sequence to be much odder than I remember. A casual search suggests that no one has ever done a true analysis of these pictures. I humbly accept the responsibility myself.

I’ll start with the pictures of people who look like the kind of folks I wouldn’t mind hanging out with in a bar. The more irksome characters are at the end of the list.

Mustachioed Barkeep

Mustachioed Barkeep

Mustachioed Barkeep


Oddly, I find this guy’s mustache to be wholesome and comforting. Maybe it’s because I lived in Brooklyn for so long. I know he works for tips, but I’m also impressed by how he manages to have one of the only non-lecherous smiles in the entire sequence. Sadly, after the death of Nicholas Colasanto, who played Coach, they removed this likable chap from the opening sequence.


The Champion

The Champion

The Champion


Also known as the “We Win” guy. Bonus: The fair-haired dude hoisting a pint always makes me think of Matt Mullenweg.


Tom Joad

Tom Joad

Tom Joad


The dude with the Jed Clampett hat and the five-o-clock shadow is pure salt-of-the-earth. I feel like most Woody Guthrie songs are about this guy.


Norm

Norm

Norm


Even as a kid, I remember feeling bad that they chose an overweight guy to represent Norm. As if his weight is his only salient quality. Why not show an accountant? In any case, I respect a guy who can pull off a suit of that color. To me, one of the great mysteries has always been: what is he handing to the woman in the red skirt? The TV remote wouldn’t be invented for another 40 years.


The Madam

The Madam

The Madam


This woman seems like she’s the only drinker in the entire intro who is maintaining control over herself. I can respect that. The composition of this shot reminds me of that Renoir painting where everyone’s checking everyone else out.


Kid Gorgeous

Kid Gorgeous

Kid Gorgeous


The pale fellow in the jacket doesn’t look old enough to be drinking in this establishment, and his complexion makes me suspect that he’s nervous about being caught. I always imagine him as having been a 12-year-old drummer boy for the Confederate Army, returned to his local tavern as a 17-year-old amputee veteran. Notice that his legs are not visible in this picture.


The Cognac Brothers

The Cognac Brothers

The Cognac Brothers


Does he really need that cane? Or is he just trying to intimidate? Is he the bouncer, or just waiting for his carriageman to bring the team around? So many questions.


Rich Uncle Pennybags

Rich Uncle Pennybags

Rich Uncle Pennybags


You can’t afford what this guy is drinking.


Top Hat Asshole and Smarmy Newsboy

Top Hat Asshole and Smarmy Newsboy

Top Hat Asshole and Smarmy Newsboy


The two most insufferable people in the sequence are also the last two, and boy, do they leave a bad taste in your mouth. Both are clearly looking to start a fight. The guy on the left, apparently drinking a $20 Trappist ale, is barely managing to hide his disdain for everyone around him. The dude on the right appears to be bragging about hooking up with your sister. (The guy in the bottom right, who looks as if he may in fact be dead, has pretty much checked out of the party.) I hate them so much.

Chicago

I’ve spent a lucky thirteen years in New York City, but my time here is drawing to a close. My wonderful wife is entering a PhD program at the University of Chicago in the fall, so this summer we’ll be trading the First City for the Second.

I’m trying to untangle my thoughts about leaving my adopted New York and returning to my native Midwest. It’s heartbreaking, thrilling, terrifying, a huge relief. For the moment, I can say with confidence that I am excited to be relocating to a city that’s served as the setting for so many great theme songs. Nothing’s gonna stop me now!

The number one reason to start using git: interactive staging

Git is an excellent tool for collaborative software development in a number of ways. In my opinion, Git’s most valuable feature – which also happens to be one of its most underappreciated – is interactive staging: git add -i and git add -p. If you are a software development who does not use Git, or if you use Git but do not use this feature, you should not write another line of code until you learn it.

When working on a large project, there is no principle more important than that changesets are atomic. Combining more than one distinct change into a commit is highly detrimental to a project’s history. Muddled changesets are hell for future developers on the project, including Future You. The usefulness of log, blame, bisect, and (not to get hyperbolic or anything) version control itself, depends on commits being logically small units.

But, of course, software is not built linearly. You’re writing cool new feature X, but you notice that in order to complete X, you need to fix bug Y. The problem is that you’re already halfway finished with X. You could: generate a diff file, stash/reset your changes, fix Y, commit the fix to Y, reapply the X diff, and continue work on X. This is a pain. Or you could: commit a large changeset that contains X and Y. But this is lousy for the reasons described above. Ideally, you would be able to fix Y, continue with X, and then sort out the changesets just before commit.

This is what Git’s interactive staging lets you do. Start with a clean index. Begin hacking on X. Stumble on Y. Fix Y. Complete X. Then use Git’s stage to commit Y and X separately.

Here’s a real example. (What follows is a pretty basic situation. git add -p is a subset of git add -i, which is full of whiz-bang goodies.) Say I’m working on fixing some poor localization in BuddyPress. While doing so, I notice that some PHPDoc is missing. So I fix both issues, and git diff shows the following:

is1

Now, I know that Changesets Should Be Atomic, so I want to commit the documentation changes separately from the bug fix. So, instead of git commit -a or git add . – which blindly stage all changes – I jump into patch mode with git add -p:

is2

Git has determined what it considers to be the first “hunk” of changes. (Hunks: it takes one to know one.) I’m then asked whether I want to “Stage this hunk”. Normally I’ll just type y or n, but in this case I see that Git hasn’t made the hunks small enough, so I choose s, for “split”:

is3

The hunk is now split into two. The first sub-hunk is the documentation fix. Let’s stage it with y. The second sub-hunk is the code fix, which we’ll skip for now with n. Rinse and repeat with the second big hunk. git status now shows the following:

is4

The “changes ready to be committed” are the documentation fixes. These can be viewed with git diff --cached. The “changes not staged for commit” are the code changes. These can be viewed with git diff. I’m now ready to commit the first set of changes:

is5

(I typed that commit message in my $EDITORvim – which you can’t see in this screenshot.) Then I’ll repeat the routine for the next set of changes, this time staging them all:

is6

Git’s interactive staging is relatively simple, but will completely change the way you work, in ways that will result in meaningful improvements to your projects over time. This is, IMHO, the #1 reason to use Git, and if you’re not using it – because you’re an SVN user, because you didn’t know about it, because your GUI client doesn’t support it – it’s important enough that you ought to think about changing your toolkit.

I miss my camera

It’s been almost a year since I ditched my smartphone. For the most part, it’s been glorious. Like a slow-growing tumor, I’d hardly noticed the damage that years of carrying a smartphone was doing to my lifestyle and my psyche.

The one thing I legitimately miss is the camera. In one sense, I’m glad to buck my generation’s tendency toward hyperselfdocumentation. At the same time, I have kids. I took many hundreds of photos and videos of my first child on my smartphone. I’ve partially compensated for this with the second child by strategically storing cameras in various parts of my apartment, so there’s always one at hand. In the house, this works. But, with the approach of warm weather, I worry once again about the hassle of filling yet another pants pocket with yet another device.

Friends have suggested that I get a smartphone but don’t use the data. But this is like suggesting that I replace my extracted tumor, but this time put it a little further from vital organs.

I feel like I’d be more likely to carry a point-and-shoot camera if they were more svelte. If the iPhone 6 can take such beautiful pictures, why doesn’t someone market a standalone camera with the proportions of a smartphone? The thinnest cameras I’ve seen are double the thickness of even the bulkiest modern phone – way beyond the point of pocketability. Is there a device out there for me?

phpunit-speedtrap and WordPress/BuddyPress automated tests

One of my personal missions over the last six months has been to shave seconds off of the WordPress and BuddyPress automated test suites. (WP’s tests run in under half the time today than in WP 4.0 – and with the addition of nearly 1000 tests. Score!) One of the tools I use to track down problematic tests is John Kary’s excellent phpunit-speedtrap, which adds a listener to each test run, and produces a report of tests whose running time exceeds a configurable threshhold. phpunit-speedtrap is designed to be used as a Composer dependency, but this is not currently convenient or necessary for the purposes of working with WP/BP (for one thing, I’m the only person doing it). Here’s how I’ve rigged it up to run locally:

  1. Grab a copy of the listener class from Github https://github.com/johnkary/phpunit-speedtrap/blob/master/src/JohnKary/PHPUnit/Listener/SpeedTrapListener.php. I chose to remove the PHP namespacing, but you can do as you wish. Save it somewhere – I put it at ~/.speed-trap-listener.php so that I can use it with all projects.
  2. WP and BP ship with a phpunit.xml.dist config file. The .dist extension means that you can run your own phpunit.xml alongside of phpunit.xml.dist – PHPUnit will prefer the non-dist version if available, while WP and BP’s version control config will ignore it. Copy phpunit.xml.dist to phpunit.xml and add the following block:
        
    	<listeners>
    		<listener class="SpeedTrapListener" file="/home/bgorges/.speed-trap-listener.php">
    			<arguments>
    				<array>
    					<element key="slowThreshold">
    						<integer>250</integer>
    					</element>
    				</array>
    			</arguments>
    		</listener>
    	</listeners>
    

    Change the slowThreshold and filepath to whatever you’d like.

  3. Run phpunit. You’ll see something like this:
    Screenshot_2015-03-07_11-50-30

Keep on shavin’!

2014

Reflecting on 2014, a couple of themes:

  • Reclaim. In the past, I’ve written about taking back technologies from corporate entities. This year, I’ve found myself embarking on what I consider to be the natural extension of Project Reclaim: taking back my attention from technologies. In April I ditched my smartphone, and in September I stopped using Twitter. Each decision arose from a desire to devote more of my limited mental and emotional energies on things that matter most to me, like my family and my work. In each case, the pull of inertia was strong – the natural thing was to continue using the tools, just like everyone else around me was doing – but in each case, the rewards of letting go have been significant.
  • Ease. My wife and I decided over dinner tonight that 2014 felt easy. We didn’t move this year. We enjoyed satisfying jobs and financial stability. Our son transitioned from a toddler to a very nice little boy. In contrast, our family has a number of very large changes coming in 2015, changes that will be hard in many ways. So the relative and welcome easiness of 2014 is worth a moment’s pause.
  • ShippingDuring 2014, BuddyPress shipped a number of major versions. I put a huge amount of time into BP 2.0, as both a developer and a release manager, and I think it paid off – IMHO it’s one of the most important releases in BuddyPress history. BuddyPress 2.2 will come in the first weeks of 2015, and it too promises to be a really important release. In addition, I was invited to join the WordPress core team for the 4.1 release, an experience that’s been fulfilling in its own way. Considered alongside a number of successful client project launches, I’ve been involved in a happily large number of solid software releases this year.

A big year ahead, but for now, за ваше здоровье!