It has recently been birthday season in my family. Angela, Dad and I all have our birthdays within an 8-day period at the start of June. While we were out for dinner at a Sydney restaurant, there was discussion of whether a cakeage fee would apply at the restaurant.
What is cakeage? It’s a per-person fee charged by a restaurant to serve a dessert you have brought to the restaurant, typically a birthday cake. The term, as far as I can tell, is a neologism derived from corkage — a similar fee changed to serve a bottle of wine brought by the customer.
I’m not sure where I sit on the debate over whether cakeage should be charged by restaurants. On the pro side, the restaurant loses the ability to sell you any of their delicious desserts. Usually the cakeage fee is much less than the price of a dessert too. On the anti, there’s not much effort put into serving cakes at many restaurants (we normally take our own candles and matches, for example) so what is the charge actually for? On the balance, I’d probably say that I’m okay with restaurants charging fees like this, as long as they’re clearly advertised. It then becomes a matter of competition between restaurants, where the customers can decide whether they’re willing to pay such fees and vote with their feet.
In the end, I don’t think we were charged cakeage by the restaurant. Even if we were though, it would have likely been a very small component of the final bill.
On the topic of cake, there’s been a bit of fanfare recently about the upcoming release of Portal 2 by Valve Software. The original Portal game is one I’ve only become familiar with recently, since Valve released the game on the Mac. However, it is one of the most engaging and interesting games I’ve played in years so I thought I’d write a little bit about it. (The reference to cake is in the game; you’ll get it when you play it.)
You start the game in what appears to be a scientific research facility. You’re standing inside a large glass box with a bed and a radio. After a few moments, a portal — which looks like a large mirror with a bright blue border — appears on one of the walls inside your glass box. There is also a corresponding portal with an orange border on the wall of the room outside of your glass box. Stepping through the blue portal takes you to where the orange portal is, outside the glass box, where you start playing the game.
The initial stages of the game have you stepping through existing portals, but you quickly acquire a portal gun, which allows you to create blue and orange portals of your own. You can create portals on almost any horizontal or vertical surface in the game. The challenge of the game is to use these portals to navigate your way through a bunch of levels with a variety of hazards.
What is perhaps most interesting about the game is the game physics used when moving through a portal. Wikipedia has an excellent diagram:
![]()
Portal physics diagram
Momentum is preserved when moving through a portal, so you can use gravity to accelerate you vertically into the blue portal, then position the orange portal such that this is translated into horiztonal velocity and helps you reach an otherwise unreachable location.
Not just momentum is preserved, however. Your angle and direction-of-view relative to the portal are also preserved when you exit the portal. This makes jumping through some portals quite visually exhilirating when you come out “upside down” and gravity quickly swings your view around the right way up.
All in all, it’s a very impressive demo of what Valve’s game engine is capable of. Portal is an incredibly addictive puzzle game with the immersiveness of a first-person shooter. I’d really recommend checking it out, and if you don’t want to pay $20 for a game that’s two years old (I got my copy for free), definitely keep an eye out for Portal 2 coming later this year.
Since I started talking about buying an iPad about two months ago, people have been asking me what I’d use one for. I have a laptop. I have a desktop computer too. What would I need another computer for? And one without a keyboard at that!
I picked up an iPad 3G on Friday when they went on sale in Australia. So now, rather than hypothesizing, I can now share a few interesting uses I’ve found for it in the last three days.
It isn’t earth-shattering stuff. A lot of normal things you could definitely use a laptop or a desktop computer for. I’ve found it’s two small differences that make the iPad stand out. First, it really is very quick to pick up and use. Launching the web browser takes a fraction of a second and the browsing itself is really responsive. Second, the iPad is incredibly shareable. You just hand to someone if you want to share something with them. Interacting with it is intuitive and simple, even for someone who hasn’t used an iPhone or iPad before. These two things makes all the tasks above simpler and just more fun.
Apple has now sold over two million iPads, so there must be a few readers with one too. What do you use an iPad for?
One of the frequently-cited problems with JavaScript is its lack of support for modularisation. It’s particularly problematic now that web applications are becoming more interactive. Structuring a number of AJAX calls and related functions proves to be a big problem if you want to avoid using the global namespace yet want to split your logic into separate files or functions without a shared scope.
There are several frameworks that attempt to address this and features have been proposed for the next version of ECMAScript. However, one simple solution we’ve been experimenting with on the Confluence team is using the browser’s built-in event system — underneath the event abstraction provided by jQuery — to modularise operations in large JavaScript features. That has enabled us to split up our JavaScript logic much more easily and reduce the number of JS files with more than 100 lines of difficult-to-follow script.
A bit of JavaScript that sends off an AJAX request, processes it and also responds to a user’s action on the form might look like this:
jQuery(function ($) {
function addLinkToList(link) {
$("#link-list").append($(AJS.template.load("link-item").fill(link));
}
$.ajax({
url: '/get-links.action',
data: { ... },
dataType: 'json',
error: function (xhr, message) {
alert("Failed to retrieve links: " + message);
},
success: function (data) {
$.each(data.links) {
addLinkToList({
name: this.name,
url: this.url
});
}
}
});
$("#add-link-button").click(function () {
$.ajax({
url: '/add-link.action',
data: { ... },
dataType: 'json',
error: function (xhr, message) {
alert("Failed to add link: " + message);
},
success: function (data) {
addLinkToList({
name: data.name,
url: data.url
});
}
});
});
This example demonstrates the fact that both AJAX operations – one that runs initially and one that runs when the user clicks a button – rely on the same function, addLinkToList. This tight coupling gives you very few options for modularising this code in JavaScript if these functions grow large and would best be separated into different files. Most often we’ve ended up making shared functions accessible in the global scope or assigning them to an existing global object (like a DOM element) for subsequent retrieval. Neither option is particularly clean.
The new method we’re experimenting is to use event handling to allow simpler modularisation and data passing between unrelated pieces of JavaScript code.
Here is the same code using jQuery’s event handling to publish a “add-list-item” event when the AJAX calls return:
jQuery(function ($) {
$(window).bind("add-list-item.link-list", function (e, data) {
$("#link-list").append($(AJS.template.load("link-item").fill(data));
});
$.ajax({
url: '/get-links.action',
data: { ... },
dataType: 'json',
error: function (xhr, message) {
alert("Failed to retrieve links: " + message);
},
success: function (data) {
$.each(data.links) {
$(window).trigger("add-list-item.link-list", {
name: this.name,
url: this.url
});
}
}
});
$("#add-link-button").click(function () {
$.ajax({
url: '/add-link.action',
data: { ... },
dataType: 'json',
error: function (xhr, message) {
alert("Failed to add link: " + message);
},
success: function (data) {
$(window).trigger("add-list-item.link-list", {
name: data.name,
url: data.url
});
}
});
});
The difference is subtle: instead of calling the function directly, the AJAX functionality calls $(window).trigger("event-name.namespace") and the functionality which updates the list is bound with $(window).bind("event-name.namespace"). The data is passed to the event handler as the second argument of the call to trigger.
The code isn’t any shorter, but it is significantly less tightly coupled. You can now move each block of code into a separate file because they no longer need direct access to a shared function.
The event dispatch in this case is done through the global window object. Custom events don’t propagate through the DOM tree the same way as normal browser events, so it’s necessary to pick a shared object for use in custom event dispatch. If the events are specific to a certain area of the page, you could use a specific element instead — it just has to be consistent between the code triggering and the code receiving the event.
We could continue this approach with the code above by also extracting the common error handling functionality into an event handler. As more dynamic functionality is added, and more code required, you can add new events to handle these changes.
Event handling like this is provides much more modularity than the approach of using shared functions. The event handling model matches very closely with the way AJAX and user-driven functionality works in the browser and in the short time we’ve been using it we’ve found it a great way to improve the modularity of our JavaScript code.
My colleagues Agnes and Dmitry developed the proof-of-concept and initial implementation of this idea in Confluence. Any mistakes in the description above are mine.
Although it’s barely been visible in the last couple of days, I noticed a tiny crescent moon peeking through the clouds on Sunday night in Sydney. Astronomy Picture of the Day has this great shot of both Venus and lunar crescents:
I’ve heard a misunderstanding of the crescent moon that the roundedness is caused by the shadow of the earth. This isn’t actually the case — half the moon is always in shadow and the rounded shape we see is the result of the shadow being projected across the moon’s spherical surface and viewed on an angle from the earth. Wikipedia’s article on the phases of the moon has several explanatory diagrams.
Mark Bowden has a great article, The Enemy Within, which describes how the Conficker worm infected millions of computers worldwide:
… because so many people fail to apply the patches promptly, and because so many machines run on illegitimate Windows systems, Patch Tuesday has become part of Microsoft’s problem. The company points out its own vulnerabilities, which is like a general responsible for defending a fort making a public announcement—“The back door to the supply shed in the southeast corner of the garrison has a broken lock; here’s how to fix it.” When there is only one fort, and it is well policed, the lock is fixed and the vulnerability disappears. But when you are defending millions of forts, and a goodly number of the people responsible for their security snooze right through Patch Tuesday, the security bulletin doesn’t just invite attack, it provides a map! Twenty-eight days after the MS08-067 security bulletin appeared, Conficker started worming its way into unpatched computers.
Security specialists still aren’t sure what the attacker intends to use the massive network under his control to accomplish.
Very often when working in an application, you deal with data of variable length. File names provided by users, titles that can be arbitrarily long, all these need to be catered for.
Fitting this variable length data into a grid or fixed layout in a web interface can be problematic. The current crop of browsers only has limited support for shortening content so it can fix in a fixed amount of space.
This week I’ve been working on a more general mechanism for shortening text until it fits within a predefined width. Specifically, I need a solution that worked for breadcrumbs where there was a maximum total width for the breadcrumb, and the left-most breadcrumb items are less important than the right-most. Therefore, the left-most breadcrumbs should be abbreviated first.
Here’s a demonstration of the JavaScript I came up with: abbreviation demo.
The JavaScript to shorten text this way is quite simple. It uses jQuery for simplicity, but would work quite well in core JavaScript as well. Below is the guts of the algorithm.
function abbreviateUntil(element, condition) {
var children = $(element).children();
var current = 0;
while (current < children.length && !condition.call(element)) {
var $child = $(children[current]);
if ($child.text() == "\u2026") {
current++;
continue;
}
if (!$child.attr("title")) $child.attr("title", $child.text());
$child.text($child.text().replace(/[^\u2026]\u2026?$/, "\u2026"));
}
}
In the real implementation, this function is wrapped in a jQuery plugin that you use like this:
var fixedWidth = $(".fixed").width();
$(".fixed ul").abbreviateUntil(function () {
return $(this).width() <= fixedWidth;
})
More information on how to use the code and how to construct the markup and styles is available on the demo page. Please let me know If you have any ideas on how to make this more generally useful.
Even though he’s talking just about the development of his iPhone application, Buzz Andersen hits the nail on the head about why quality matters for the long-term success of any software product:
One of the hardest things about shipping Birdfeed was staying committed to slaving away on such minutae while other, often less polished, clients beat me to market.
While such attention to detail may not be appreciated in the specific case, however, I’ve found that in aggregate it leads to an overall impression of quality that attracts the kind of fanatically devoted users who form the backbone of a growing, long term user base.
Attention to detail is the only way to develop high quality software, and high quality software is what leads to users so happy to use your product, it sells itself by word-of-mouth.
Early next week, Liz and I are heading off to China for a long holiday. We’re travelling for eight weeks, with only the loosest of itineraries. It’s going to be an exciting adventure into the land widely regarded as having the worst toilets in the world.

Note: Artist’s impression. Actual boat may vary.
Unfortunately, we’re not really going to catch a slow boat there. Rather, we found incredibly cheap return flights from Sydney to Macau with Viva Macau. From our starting point in Macau, we plan to travel across most of the provinces in southern China over the following weeks.
Some might remember that I was learning Mandarin last year. My studies haven’t really progressed very far. If I’m lucky I might manage to be understood while saying ‘hello’ or ‘goodbye’. Anything more complicated, and I’m likely to get chased out of town for referring to somebody’s mother as a horse. (Um, yeah, I guess that’s an in-joke for Mandarin speakers.) Certainly, the language barrier is still going to be one of the biggest challenge in our travels.
I’ll be trying to post pictures from the trip as we go. Watch my Flickr account for updates on that front.

Join us for farewell drinks at Red Oak
If you’d like to see us off, Liz and I will be having will be some farewell drinks this Friday, 15 May at the infamous Red Oak Beer Café. We should be there from around 6pm if you want to catch up before we go.
Recently, I’ve become a fan of using proper punctuation in web pages. This includes simply expanding the range of punctuation I use to include a variety of dashes, fractions and symbols, and also the use of correctly curled quotation marks and apostrophes.
Even for the enthusiastic, entering the proper quotation marks manually is a pain. On Mac OS X, you need to hold down the option key and remember which of the unmarked bracket or brace keys corresponds to your desired quotation mark. On Windows, it’s even more painful to locate the quote with the character map or keyboard shortcut.
To solve this problem, I’ve written a new Java library, Smart Quotes, to automatically correct "straight quotes" to “curly quotes” in Java web applications like Confluence.
Even now, a Google search for “Java smart quotes” or “Java curly quotes” returns lots of results about how to remove the quotes rather than add them! While curly quote removal is a very simple search-and-replace, inserting correct curly quotes is a bit more of a hairy problem. You need to correctly curl the double quotes the right way, and recognise the distinction between apostrophes and single-quoted phrases.
Smart Quotes processes HTML documents. It replaces straight double or single quotes only in the text sections, avoiding the tag attributes and preformatted blocks like <code> and <pre>.
For example, the following markup:
"Occasionally, quotations may contain 'internal <em>quoted passages</em>', which shouldn't confuse one's quote-curling library."
is correctly converted by Smart Quotes into this HTML:
“Occasionally, quotations may contain ‘internal quoted passages’, which shouldn’t confuse one’s quote-curling library.”
This would work the same, even if the content were sprinkled with HTML tags.
The Smart Quotes source code contains a large number of tests that verify the quoting behaviour, interaction with tags, and so on. If you use the library and find bugs, please consider submitting a patch with a test case.
You may remember that when I started using Markdown on my blog, I also added SmartyPants. SmartyPants is a Perl library which does the same job as my new library, and I’m indebted to it for a lot of assistance with the algorithm and the original inspiration for the project. While SmartyPants already solves this problem very nicely in Perl, it isn’t suitable for integration into a cross-platform Java application.
To integrate Smart Quotes usefully in Confluence, I’ve written a Smart Quotes macro plugin. This plugin takes any other Confluence wiki content as its body, and automatically replaces the quotes throughout. For this reason, you can just wrap the entire contents of the page in a {smart-quotes} macro to get proper curly quotes.
I’m hoping the Smart Quotes library proves useful to the many Java web application developers who would like proper punctuation in their web pages. It’s available under an Apache open source license, so you can reuse and redistribute it under very flexible terms.
Yesterday, Sun was acquired by Oracle for $9.50 a share. Oracle CEO Larry Ellison is quoted in the New York Times:
He said Java, the language used in most computer science schools and a technology used daily by millions of software developers, was “the single most important software asset we have ever acquired.”
It worries me that Larry considers Java a “software asset”. Assets must have some value to the owner. What is the value of the Java programming language to Oracle? Perhaps the ability to better sell Java consulting. Or maybe, repositioning WebLogic as the standard Java enterprise platform.
Regardless of what the primary commercial benefit is for Oracle, it’s unlikely to have much to do with improvements to the language and the platform which help the average Java developer.
As a developer who works with Java quite a bit, I see the development of the programming language not as an asset but as a liability for a company. It’s a lot of time-consuming work with very few commercial benefits. Assuming the buyout is approved by the regulators and Sun’s shareholders, it will be interesting to see what Oracle does with their so-called asset in the next few years.