The impressiveness of ugly hacks

If you've been a programmer for any length of time, you've probably seen lots of hacks designed to work around limitations of a particular language or toolkit. You may have even come up with some yourself. They're a mainstay of programming.

Thing thing about hacks is that we all know we're not really supposed to use them. At least, those of us who are moderately competent know that. Of course, sometimes we use them anyway, either because we have no choice or because the alternatives are just as bad (like all the nasty CSS hacks for Internet Explorer), but we're generally not happy about it. Coming up with hacks is more like a game. It's an excuse to push the technology to its limits, to see how far we can bend it to get what we want. And if you have enough knowledge and, just as importantly, imagination, you can do some pretty impressive things.

I started thinking about this last night when I came across what I considered a very impressive hack for PHP. The limitation it addresses, is that PHP binds the self keyword at compile-time, rather than run-time. The up-shot of that is that if you have a static method foo() in a base class Fizz and override it in a child class Buzz, any methods in your base class that call self::foo() will always use the implementation in Fizz, even if they're called through Buzz.

There was a work-around for this limitation in the comments on the get_class() page on php.net. This particular hack used a trick I never would have thought to consider - using the results of the debug_backtrace() function to loop though the call-stack and determine the class of the calling method.

Just stop and think about that - using a debugging function to control how calls to class methods are resolved. It's both brilliant and completely insane. It just feels wrong - like you're going way too far for a piece of functionality that's easily achieved by using a different approach (i.e. instance methods). If I ever saw one of my co-workers put that in our codebase, I'd beat him in the head with a keyboard until he apologized. And yet, at the same time, it makes me smile, because this is one of those things you really shouldn't be able to do, and yet you can.

You can reply to this entry by leaving a comment below. You can send TrackBack pings to this URL. This entry accepts Pingbacks from other blogs. You can follow comments on this entry by subscribing to the RSS feed.

Pingbacks

Comments #

    Reflection

    This is actually close to where a lot of new paradigms in programming languages is going, particularly in the areas of reflection. Although I don't think that Java allows viewing of the call stack, it is definitely possible to find out lots of type and signature information about anonymous objects. Others allow deeper interactions (and modifications) to be performed, including some modified kinds of C++.

    An interesting parallel is in the discussion of AspectJ, an aspect-oriented programming language. Just because the function has "debug" in its name doesn't mean that it's just useful (or wise to use) for debugging. http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20010087661_2001143786.pdf

    • Comment posted on Wednesday 6 Aug 2008 at 3:46pm
    • By Matthew

Add your comments #

A comment body is required. No HTML code allowed. URLs starting with http:// or ftp:// will be automatically converted to hyperlinks.