Thursday, September 30, 2010

The Great (Lucky) Refactor

I got a new feature added to animate-frames last night. Getting there made me realize that the code is a bit messy so tonight I refactor!

Animate-frames is a plugin for raphaël.js that iterates through a series of raphaël/SVG frames as the frames move about the paper. I am using this in my (fab) game to draw and animate players as they move about the game room. I am going to refactor in the game before extracting the changes back out into the plugin.

The refactoring is necessary because many of the methods in the plugin look like:

Ah, much better. No more worrying about what that j variable was iterating over. No more trying to discern which of those 6 lines are important. Just one clear iteration through each frame in the animation, telling each frame to stop().

Again, nice and compact. Just one iteration making it very clear what is going—working through each part that makes up the frame and telling it to stop.

I end up working through half a dozen similar methods. All sorts of weird naming becomes easier (translate_object() becomes just translate() on the Frame object). Initialization code gets separated in much easier to read ways. It is great.

And then something amazing happens....

I load it up in the browser and it just works! I have no tests (note to self: future idea for a chain post) that helped me support the refactoring. Git diff reports:

That is a lot of non-trivial change. I had to intentionally break the code to make sure I was running the updated code (I was).

Amazing? Am I that good?

Absolutely not. That was pure luck and I damn well know it. The coding gods should have punished me severely for even attempting it. I give them thanks for going easy on me tonight, but I know I have a doozy of a refactoring fail in my future.

One thing I do notice is that I repeat myself in the simple raphael methods: