Tuesday, 28 February 2012

Creating a function with a true name defined at runtime

I used to have an article here showing how to dynamically create functions with true names. Except it didn't work properly on Firefox and there's a much better way (which does work properly on Firefox) described in this article by Marcos Cáceres. It looks like this:

var name = "foo"; 
var func = new Function(
     "return function " + name + "(){ alert('sweet!')}"
)();

Yes, the Function constructor is basically a call to eval, so you'd only do this with input you control well. But when you need to do it, this is how.

Nice one, Marcos!

Sunday, 26 February 2012

Google Code - Error retrieving directory contents

I dropped by one of my Google Code projects, a trivial little jQuery placeholder functionality shim called place5, and was quite surprised to see, on the Source tab, the message "Error retrieving directory contents". Now, I have backups (and you do too, of anything you host externally, right?), so I wasn't panicked or anything, but I was still...jarred.

Some searching around revealed that people get this when they've changed their source control system (e.g., from mercurial to git, or subversion to mercurial, etc.). I hadn't changed my source control system, but looking at the Source tab again I saw that it was showing an empty git tree (with the error), and I thought: "Was I using git for this?"

Answer: No, I wasn't. I'd been using subversion. So what the...? So off to Administer, and under Source | Repository Type it said "default" (which appears to [now] be git). Setting it back to subversion corrected the error and restored source browsing.

I mention this for two reasons: Firstly, I figure I won't be the only one, so I thought I'd write this down in case someone runs into the same problem and finds this post. But secondly, it highlights a general principle: It's very useful to have your settings system have the concept of a "default" choice, so if you update defaults, people start seeing the new thing. But when you update a default that's going to break things for people, it's pretty important to change the setting for anyone using "default" to the new, specific choice for the old default. Because breaking things unnecessarily is doubleplus ungood, ya know?

Tuesday, 14 February 2012

Getting rid of "What's Hot"

Google have finally made it possible to get the "What's Hot" rubbish out of your main Google+ stream. Here's how:

  1. Go to Google+.
  2. Click "What's Hot" on the left-hand side.
  3. At the top of the page, there's a subtle little slider (basically an O on a line). Move it all the way to the left.

(If you don't see a slider at the top of your What's Hot page, just wait a day or two for the rollout to come to a server near you.)

That's it, you're done. Yay!

Friday, 10 February 2012

`forEach` and runtime cost

Just a tiny one today, mostly to write this down somewhere:

As you all know, ECMAScript5 adds forEach to arrays, where you supply a function that gets called for each element in the array. There are lots of benefits to this, not least variable scoping on the index and value variables and a bit less typing, but don't all of those function calls add up to a significant runtime cost?

No, they don't.

I got curious about it (I have a tendency to micro-optimize, which I'm trying to break myself of), so I tested it on the slowest (desktop) browser currently in use: IE6. Specifically, IE6 running in an old Windows 2000 VM I have lying around. I tested the performance of looping through a 100-entry array both with and without calling a function. Without the function call, IE6 looped through the array ~4,500 times in a second (that's 450,000 loop iterations/second). With the function, it managed ~2,000 times a second (200,000 loop iterations/second). So while that's a big relative difference (56% slower!), in real terms it falls into fergedaboudit territory: 2.78 microseconds of overhead. You heard, me, microseconds. That's 0.00278 milliseconds.

Now, I'm not going to say there aren't places where it could matter. I am going to say that they're going to be extraordinarily rare, I'd wager I'll never run into a situation where it makes a difference and nor will you. Whatever else you're doing in the loop body is totally going to wash out the function calls. Really.

Happy coding!

Wednesday, 30 November 2011

The true story on return false

In JavaScript event handlers, you'll frequently see return false; at the end. Why? What does it do? The answer is: It depends. Before we get into the details, there are basically two things it could be doing:

  1. Preventing the default action of the event, such as when you click a link and the browser follows it.
  2. Stopping propagation of the event to ancestor elements.

So which does return false do? Just one, neither, or both:

  • DOM0 handlers: In an old-style DOM0 handler, hooked up via an attribute like this:
    <div onclick="return functionName();">
    ...it prevents the default action but doesn't stop propagation. Note that you need that return in the attribute. Try it here.
  • DOM0 handlers (again): The same is true of an old-style DOM0 handler hooked up via the reflected property for the attribute, like this:
    document.getElementById("someId").onclick = functionName;
    Try it here. As before, return false; prevents the default action but doesn't stop propagation.
  • DOM2 handlers: In a proper DOM2 handler hooked up via addEventListener, like this:
    document.getElementById("someId").addEventListener("click", functionName, false);
    ...return false does absolutely nothing. Instead, use the preventDefault and stopPropagation functions on the Event object your handler receives as an argument. Try it here (be sure to use a non-Microsoft browser, or use IE9 or higher).
  • Microsoft DOM2-ish handlers: In a DOM2-ish handler hooked up with Microsoft's attachEvent function, like this:
    document.getElementById("someId").attachEvent("onclick", functionName);
    ...return false prevents the default but not propagation, just like a DOM0 handler. Try it here (using IE8 or lower).
  • jQuery handlers: Event handlers hooked up with jQuery get a twofer: return false both prevents the default and stops propagation. It's a jQuery thing.

Happy handling!

Friday, 7 October 2011

Finally!

Google announces an honest-to-goodness relational DB for App Engine: Google Cloud SQL. And it's the nice, familiar MySQL engine with virtually full support and very few limitations. Notably missing from that FAQ is anything about limits on how long a statement can take to complete (I've asked the question), but other than that...

Friday, 26 August 2011

Potentially Good News on Software Patents

There's some potentially good news on software patents. The Federal Circuit appeals court has rejected a patent claim on the basis that it's just an "abstract idea," a door that was very slightly opened in a recent very narrowly-drawn Supreme Court patent decision. Might reason ultimately prevail over avarice and bullying...? Paraphrasing something a good friend of mine said to me once, I'm prepared to believe there really are patentable software ideas. I'm not sure I'm prepared to believe they number in the thousands, possibly not even in the hundreds.