Translating Beowolf
On Dealing with Large Chunks of Old Code
One of the interesting things about writing an API against a legacy system is what happens when you run into the truly large and complex functions. I'm currently squaring off against a function that weighs in at around 1,200 lines of very densely packed Delphi code, intermingled with some SQL. This is the first time that the approach of "read the code, draw up a flowchart based on the logic, write new code based on the flowchart" has been not quite enough.
The interesting thing is that at this size and complexity, the largest problem that I have isn't one of syntax or complexity, it's structure. Between the changes in programming styles, language features, and IDE features in the past decade, it means that at least half the time tasks are being accomplished in ways that I find counter-intuitive. I'm so used to short functions, object oriented design, blocks, and event listeners that just reading a massive monolithic function is a challenge.
To try and tame the function into something that I can maintain in my own code base, I've been unwrapping each layer of logic in the function, breaking it into smaller functions and passing arguments as needed, comparing the logic multiple times, then moving down to the next layer.
I'm hoping that after I've rewritten the logic into smaller functions I can give my own code a once over and eliminate redundant, or dead code, and then write a flowchart for the logic for later reference.
The one interesting side effect of this is by going over the existing code with such a fine toothed comb, I've found a few minor problems that weren't caught, because they effect such a minor and exotic part of the final output that nobody ever noticed, or possibly even the cases where the bugs would change the data have never been hit.