Because I'm working on a set of badly coded scripts where loads of global
variables exist (ie: no 'use strict' in effect) that may be modified in any
one of numerous subroutines over three different and fairly large modules..
If it were me, I might start by using strict (and warnings.)
This will (obviously) throw compile errors for undeclared variables.
Then you can declare your variables, starting with the top scope and
working your way down to the inner scopes. At least see where they are
scoped.
Another thing I might do is make control flow graphs showing the flow
of control for your program. I have found this to be a very useful
tool.
If you are a bottom up developer, I'd write drivers for your modules,
and test the routines in your modules to see if they do what they are
supposed to do. If you are a top down developer, I'd write stubs for
your called routines to see the absent functionality. I've only been
involved in a project like this a couple of times, but I've had luck
doing both and meeting in the middle.
Another thing that's worked for me is a functional style of
programming where routines only accept arguments and return values --
that is, they avoid side effects unless they specifically produce a
side effect (like 'print_comma_delimited_file(\@data_array_ref)'), and
then they only produce the side effect.
Good luck, CC.