» 2008 » August

Archive for August, 2008

Film Fight: July 2008

Saturday, August 23rd, 2008

Only 4 films this month:

First up is Frank Darabont’s take on Stephen King’s The Mist. Amongst filmed versions of King’s work, it ranks amongst the most subtle and controlled pieces. Rather than explicitly showing everything that happened (creatures coming from another dimension and covering the world in a deep fog) and giving us another brainless monster/horror piece, Darabont has focussed on the real heart of the story: the tension between believers and non-believers, through a fairly cunningly chosen bunch of set-pieces. Slowly, different fears and prejudices seep through a group trapped in a supermarket until they inevitably turn on one another. The way this is done is masterful, and the climax is pretty heartbreaking, cheapened only slightly by an unnecessary denouement. The characters themselves are fairly one-dimensional, but that’s the point: they’re only aspects of ourselves. Very strong, subtle film-making, though perhaps a shade on the long side. Recommended.

Jack Black continues to dominate Hollywood, moving into animated shenanigans with Kung-Fu Panda, the story of a martial arts-obsessed panda who becomes entangled in a years old grudge match to become the best at kung-fu. It’s happy enough, has plenty of laughs, and neat pieces, but is let down by a fairly mediocre performance by the titular character. Black is doing a watered down version of his normal schtick, without really emoting. He’s a great presence, but not much of a voice actor. Still, there’s enough in the film to make it watchable and even enjoyable.

Pixar, on the other hand, are a powerhouse of animated movies and their latest release, Wall-E, is no exception. This story of a lonely robot and his first love is set against the backdrop of environmental disaster, and humanity’s laziness. Suffice to say it all works out the way you’d expect, but the story is still worthwhile. More interesting is the style in which the story is told: almost no dialogue, beautiful animation and lots of brilliant realised characters. While it doesn’t go into great depth on any of the key themes, something that is to be expected from a kid’s film, it is a great story and well told. Another hit for Pixar.

Finally, Christopher Nolan continues to redefine the superhero genre in The Dark Knight. I’ve discussed this film more than any other in recent memory and I agree with the pervading feeling: it’s extremely good. Heath Ledger is incredible as the Joker, the tone is well set, the cinematography is exceptional, and it’s a thoroughly enjoyable film. That said, it’s not without flaws. Most notable is the burgeoning length and lack of clear focus. Building up Harvey Dent for the fall to become Two-Face was necessary, but then cramming so much of the character into the back half of the movie? It felt forced and pushed the film longer than it could comfortably sustain; that strand could and should have been picked up in the next part of the series. There’s plenty of other cuts that could be made: most of the cast being rendered mere scenery compared to the scene-stealing joker. I could go on (and have in conversation) with list of problems with the movie, but ultimately I enjoyed it, and thought it was a compelling piece of film-making. I recommend it highly.

I’m a little torn for this months’ winner: should it be a subtle horror movie, a brilliant but light story, or a flawed but enjoyable blockbuster? They’re all great films, but I think it’s going to be The Dark Knight, largely due to Ledger’s perfectly-pitched attempt at the classic Joker character.

Fixing a Gap in Javascript

Tuesday, August 19th, 2008

An interesting problem: a bunch of Struts Nested tags generate HTML. Separately, we write some Javascript that makes use of getElementById() to find some of the generated elements. This works in Internet Explorer, but fails miserably in FireFox. Why?

Well, it turns out that Struts Nested tags generate elements that have a name attribute but not an id. Separately, IE actually does the wrong thing with getElementById(): if a search by id fails, it will try to match by name; that’s fundamentally broken. It’d be fine if a bunch of libraries and other functions didn’t prefer the use of ids, and if other browsers did the same thing. They don’t and we’re stuck with the mess. Let’s clean it up.

The right thing to do would be to cripple the IE version into the correct behaviour. Now everyone agrees on what should happen.

Let’s assume, though, that this isn’t possible, that there’s a large dependency on this behaviour that cannot be changed for whatever reason: no access to the JS, unwieldy codebase that we don’t have time to fix straight away (bad!), or something else. It’s not really that important. If you need to go for the wrong solution, here’s how:

document.nativeGetById = document.getElementById;
document.getElementById = function(id){
  var el = document.nativeGetById(id);
  if(el == null){
    el = document.getElementsByName(id)[0];
    if(el != null){el.id=id;}
  }
  return el;
}

That’ll work and it’ll even make sure subsequent calls use the native version of the function for extra speed. Now, there are a couple of small issues with this function and some pretty obvious optimisations, but I’ll leave that as an exercise for the reader.

Neater Java

Tuesday, August 12th, 2008

In Java 5, as all good Java developers will know, Sun introduced the enum type. Since I’m sure anyone who is interested in what will follow knows that already, I won’t bore you with the details but there’s some decent historical information on Sun’s reasons available. I’m going to be talking a little bit about operations on enums, so let’s get started by defining one:

public enum OrderState{
PENDING, CHECKING_CREDIT, PROCESSING, SHIPPED, RECEIVED, CANCELLED, RETURNED
}

Each of those items in the enumeration represent some state that an order can be in; an order being anything you can buy from an online store. We’re also going to have a variable called currentState which will hold one of these enumerated items. Let’s not think too hard about how accurate the model is, it’s really just there as a simple example.

Now imagine that one of our requirements is to enable a button if the currentState is one of several possible states, but not in any other state. For example, the “Cancel” button is enabled while the current state is PENDING, PROCESSING, or CHECKING_CREDIT. We’re doing a containment check, a pretty common operation. The standard Java approach would be:

if(currentState.equals(Order_State.PENDING)|| currentState.equals(Order_State.PROCESSING)|| currentState.equals(Order_State.CHECKING_CREDIT)){
    cancelButton.enable();
}

Yuck! It gets the job done but that is some verbose and ugly code. We know that there’s got to be a better way, and there is: the EnumSet class. EnumSet is a somewhat overlooked Set implementation, specifically for grouping together items from the same Enum. I’ll let you look into the details of the API, but there are some very handy methods, such as range() and complementOf(). As a bonus, they’re also very efficient. How would our example look using an EnumSet?

if(EnumSet.of(Order_State.PENDING, Order_State.PROCESSING, Order_State.CHECKING_CREDIT).contains(currentState)){
    cancelButton.enable();
}

That’s much better. Rather than a bunch of ORs that look disconnected and have a lot of repeated syntax, we state pretty clearly what we want: build a set of states, and then see whether the current state is part of that set.

There is another neater way of doing this, purely in terms of how syntactically nice it looks, though it requires a little helper function in the Enum. Add the following in() method directly to the Enum type:

public boolean in(Order_State... args){
    return EnumSet.copyOf(Arrays.asList(args)).contains(this);
}

Now, we can do our contains check like this:

if(currentState.in(Order_State.PENDING, Order_State.PROCESSING, Order_State.CHECKING_CREDIT)){
    cancelButton.enable();
}

Very tidy: we’ve got a single method call that expresses exactly what we’re aiming for in a fluent manner. Now, it does have it’s downsides like the helper function in the enum, and the fact that EnumSet is more efficient. I’d suggest, though, that in 99% of cases you’re not going to be caring about those few extra nanoseconds required to convert to a List first, and that the few seconds of developer time you save every time someone has to read and understand each version more than makes up for it.