in reply to Refactoring old modules to use roles
Okay, okay ... (let the down-votes begin, once again ...) ... let me be “the Devil’s advocate” here. The gadfly. The voice of your conscience. Or, if you prefer, the guy who “sees dead projects™” more-or-less for a living. The first thing that I want to do is to challenge your plans. To politely question why you are even considering doing this. Once you start tearing the skin off of a legacy-monster like this, who knows what sort of pus might come pouring out ...
Also: let me start right out by declaiming that I am not trying to be
an asshole condescending, nor to question your professional judgment nor greater awareness of the situation ... in any way whatsoever. Most likely, I am not saying anything that is new. If you should even begin to take offense at any of this, I most humbly beseech your forgiveness. We are colleagues, challenged to vanquish the same sorts of problems for our respective clientele. But we do not know each other. We have never met.
That being said, let me continue . . . in the vain hope that it might prove to have been worth saying.
Every legacy application on Planet Earth has a utility.pm, and it is inevitably a point of functional dependency that is common to everything. (Fortunately, a module-count on the order of 100 is really quite small.) Before you can seriously begin, or even contemplate, “–er improvements” with regard to the overall system, you will need to consider how to split-apart this module. First, you must cleanly separate the unrelated concerns that this one module now has. Then, of course, you must teach it how to make
tea double-shot espressos ... in the middle of the night.
What I am, frankly, not convinced of, is the wisdom of attempting to teach this old dog new tricks: to re-tool the thing to use Dancer2/Moo. To me, that goes far beyond the artistic-license of “refactoring,” and lands smack-dab in the camp of “rewriting the damn thing from scratch.” Which, of course, is what every programmer wants to do, when faced with a legacy application ... but which is almost never economically-justifiable against the overwhelming business risk. If you will endeavor to actually do such a thing, be damn sure that you really do have “business buy-in,” and from the highest levels.
The first thing that I would do, at this point, is to start constructing test suites. (Given that you will be doing very-destabilizing things, you must be able to quantify them.) These tests will probably be based on Selenium, and they will not be easy to construct, yet anything is better than nothing. You need to have some very-objective basis for detecting regression in the system ... which is an inevitable consequence of “having touched it” in any way. You need to build a set of “tests that run clean,” such that you can continue to automatically demonstrate that they continue to do so. Only then can you begin to carefully split-apart utility.pm.
I anticipate that there is one point of commonality that you probably will never be able to entirely eliminate ... “global variables.” But perhaps you can isolate these into their own package. This does not eliminate the problem, but it does tag it: “they all have the same use statement.”
And, finally: use
version-control git. Snapshot the system’s present state in the root-branch, then immediately tag it. Create a development branch. Then, for each distinct change that you endeavor to make ... another branch. Keep a “running log,” constantly updated, by which you “talk to yourself” (and/or your team) about what you are doing and why.
You may or may not ever actually convert this system to use Moo/Dancer2, much less Roles. Legacy systems usually continue to play by their own rules. But, you did not “fail” if you do not meet your original lofty expectations.