Don’t Commit Syntax Errors
Add this as an alias in your .gitconfig file:
Now, before you commit a batch of changes, you can run git syntax-check. Simple!
For a few other git niceties, take a look at my full .gitconfig
Add this as an alias in your .gitconfig file:
Now, before you commit a batch of changes, you can run git syntax-check. Simple!
For a few other git niceties, take a look at my full .gitconfig
No one likes it, and we all look for ways to get out of it. At StepOut the dev team has been fighting the good fight to try to deprecate support for IE6 and IE7. Unfortunately, it’s a tough business sell. No one wants to hear that they’re going to lose n% of their visits, regardless of what n happens to be.
Admittedly we should have thought to look at this sooner, but instead of simply comparing visits and pageviews, we started to dive into site usage metrics across our major browsers. The data was striking:
When you see the absolute numbers (redacted), it’s really quite astounding. The relative measures still tell the story though. Essentially, on our site, IE6 and IE7 users are 80% less engaged. Now that is data you can pitch.
A couple months back I had to implement an odometer-style counter for the new StepOut landing page. I found a few implementations here and there, but I didn’t really like any of them so I decided to roll my own. It’s not the most elegant code I’ve ever written, but it seems to work fairly well and is nice and succinct.
So how does it work?
Each digit in the counter is represented with the following HTML:
<span class="digit">
<span title="3">3</span>
<hr />
</span>
We store the value of each digit and replace the value of the inner span with a list of numbers 0-9 (well, really 1-9, padded with 0s). We then change the position of that span so that the original number is visible. During each ‘tick’, we animate the top property of the span so that the next digit becomes visible, and wrap around once we hit 0.
The process ended up being fairly straightforward, so I hope the code will be at least somewhat legible.
I haven’t done much to generalize the code, so a bit of coaxing might be required to get it to work in your environment. I do have a working jsFiddle set up though. That said, all of this is provided without warranty. I mostly hope that this can serve as an interesting reference or starting point for someone else in the future.

That’s 49 bags (probably around 30 pounds) of glorious, caffeinating goodness. Over the past year I tried to catalogue all of the coffee I brewed, and while I probably missed a few bags here and there, this is a pretty representative sample of what kept me percolating in 2011.
It was a great year for tasting and learning. Local spots like Porto Rico Importing Co. and subscription services like Craft Coffee and Tonx provided the opportunity to try different coffees from all over the world. I started the year dead set on dark roasts, but as my brew technique improved I started to appreciate the complexity across the gamut. For months, every new coffee I tried I’d declare the best in the world.
Looking back over the year, was there a single stand out? You bet!

I’d like to say this was a difficult decision, and while more than a few exceptional coffees hit my cup, none came close to the El Salvador Finca Montery Bambu from Tonx. The Coffee Adventures review of this coffee pretty much sums it up for me:
I enjoyed this coffee more than I can put words together to describe this feeling.
The aroma alone convinced fellow developer Bob Patterson to give coffee a second chance. To paraphrase his reaction, “I had no idea coffee had actual flavor”.
I thought I’d have this whole coffee thing figured out in no time, but, just like so many great pursuits, the deeper you go, the more you realize you still have to learn. It’s been a lot of fun experimenting, learning, sharing and of course, enjoying a year full of coffee.
I was lucky enough to get in on one of Tonx Coffee’s first roasts, and let me tell you, it’s some seriously good stuff. These beans came from Finca Matalapa in El Salvador.
Co-founder Nik Bauman told me that this particular roast came out a little darker than they would have liked. You can see that the beans are a really nice, chocholatey brown color. Despite being a little on the dark side, I still think this roast makes a phenomenal cup.
Earlier this year I picked up a Hario Slim Mill and it’s definitely the MVP of my coffee setup. It produces an excellent, consistent grind, and I’ve come to really enjoy hand grinding (although it does get tiring if you have to do more than one cup at a time). I also have an electric burr grinder when I’m brewing several cups at once, but it really doesn’t come close to the quality of the Hario.
I’ve been using a Clever Coffee Dripper which really nicely marries the full-immersion brewing of a press pot, with the crisp, clean cup of a pour over. The cleanup is also much easier than with the press pot, which is a huge win in my book.
I’ve tried a few different techniques with the Clever Coffee Dripper, all with pretty good results. The one I’ve settled on is fairly simple:
The entire brew process takes around five minutes, and is (in my opinion) the best combination of simplicity and predicable results.
Is all this work worth it? You bet it is! Proof below:
I get really excited when I hear business ideas that don’t rely on the “we’ll get a lot of users and then make money” approach. It’s not that it can’t work so much as it can not work.
tl;dr: Reduce overhead for towing companies (they don’t have to send out their trucks). Increase revenue for towing companies by increasing total fees paid, via basic turn-around time psychology like is used in mail-in rebates. Reduce stress and average fees paid-per-person.
Not sure if the economics are actually right, but this totally nails the conceptual model for entrepreneurship. It’s an industry where there is significant pain (bonus points for the pain exiting for both the consumer and provider) and there is a very obvious, very direct way in which to make money.
I dig it.
| locks: | well, code a clone of yourself |
| Judofyr: | but if he's *just* like me… |
| Judofyr: | … he won't do shit either |
| Judofyr: | he'll just code *another* clone |
I’m not sure how I feel about the phrase “incompetent adults”, but the article does make some great points around the unsustainable actions of the commercial coffee industry
Entire documents contained within shortened URLs. Talk about utter utility (in a good way).
I had a pretty standard pattern for memcaching expensive method calls:
$key = "MyKey";
if(!$data = MC::get($key)){
$data = some_expensive_function();
MC::set($key, $data);
}
do_stuff($data);
But I guess I copied and pasted that pattern one too many times, and decided that there really has to be a better way. Thanks to the overloading methods in PHP 5 and late static bindings in PHP 5.3.0, there is!
Let’s take a look at the code:
This class uses PHP’s __call and __callStatic magic methods to intercept any method call which does not result in a method actually being executed. We then look for two prefixes, mc_ or mcd_ to determine if the method call was intended to be processed through our cache wrapper. If we find one of those prefixes, we rewrite the method name and attempt to call the new method and cache the result.
Pretty simple concept, and super easy to use. To use this on a pre-existing class, just extend the Memcacheable class and you’re good-to-go. Here’s a fairly contrived example of a class that is now magically memcached:
And an example of how you would actually interact with the caching mechanisms:
As always, I have a few notes:
mc_ will cache the code, mcd_ will delete the code from the cache__callStatic and get_called_class() require PHP 5.3.0 or greater, if you don’t care about caching calls to static methods you can remove the __callStatic block from Memcacheable.php and it should all work in PHP 5.0 or greaterMC, you’ll need to replace these calls with calls to your own cache wrapper. I’ve provided a terribly simplistic implementation in the gist so that the code can all be run together __call prevents errors about calls to undefined methods from being thrown. It’s fine because we can throw our own error, but it feels fairly sloppyDiscussion on Hacker News