http://qs321.pair.com?node_id=905272

aartist has asked for the wisdom of the Perl Monks concerning the following question:

Hi

I have to read someone else's program and make sense out of it. I have to modify it completely for the new requirement. It has around 10000 lines. It does not use many of the standard modules that I already know. (For example: GetOpt) I have secret desire to modify it, in my way with 'Modern Perl' (OO, Moose, DBIx etc..). There are no test written for this program. I am in short supply of time. Any and all advice would be valuable. Please let me know if you need any more information.

Replies are listed 'Best First'.
Re: Reading Someone's Program
by Tux (Canon) on May 17, 2011 at 14:38 UTC
    • Reformat/reflow to your liking. Preferably with Perl::Tidy, so the new layout is both documented and reproducible.
    • Do not rewrite function-based code to OO-based code just because it is more modern. There may be (very) good reasons other than modernizing the code, but simply because you think OO is more modern or because you like OO is a very bad reason for such a conversion. To me that sounds like implementing threads in a program that doesn't gain anything by that.
    • Add comments! Everywhere that you needed time to investigate, add comments.
    • Start writing tests based on the docs and based on any fix you make.
    • Replace local option parsing functions with Getopt::Long and write a good usage function.
    • Create a two-sided TODO list. On the left "Have to change", on the right "would love to change". Postpone the right until everything works and you have spare time.
    • Use a good VCS, like git and commit often with very clear commit messages.

    Enjoy, Have FUN! H.Merijn

      A good rule of thumb for the "often" part of local committing is:
      you've changed something and managed to get it to compile again -> commit!

        "managed to get it to compile again" o.O? I'm going to assume you mean "have added thorough tests for the changed code and confirmed they all pass".
        Me
Re: Reading Someone's Program
by moritz (Cardinal) on May 17, 2011 at 14:11 UTC

    I'm sure you'll find lots of discussions when you search for "legacy code".

    Just two points:

    App::Ack is like a better grep, and very valuable for finding where specific variables/functions/methods are used.

    The more change, the more you break. If lots of work has been put into the old code base, it might be worth to change only the bits you need to change, instead of introducing massive-scale changes like porting all classes to Moose. (Of course that doesn't apply if you have to touch nearly all code anyway).

Re: Reading Someone's Program
by maio (Acolyte) on May 17, 2011 at 15:24 UTC
    Google for Working Effectively With Legacy Code book. Either buy it, which I highly recommend or at least read chapter which is free @ WorkingEffectivelyWithLegacyCode.pdf
    1. Identify change points
    2. Find an inflection point
    3. Cover the inflection point
      a. Break external dependencies
      b. Break internal dependencies
      c. Write tests
    4. Make changes
    5. Refactor the covered code.
    
Re: Reading Someone's Program
by Corion (Patriarch) on May 17, 2011 at 14:07 UTC

    Cut the blue wire!

    Update: Sorry, I meant the red one.

Re: Reading Someone's Program
by Your Mother (Archbishop) on May 17, 2011 at 16:34 UTC
    I am in short supply of time.

    If this is really, really true: don't try rewrite anything excepting the exact requirements you've got. Just try to understand what's there, extend it, and blend in with it.

    As you go, after you've had time to understand the code better and what exactly it does, write tests. Rewriting without taking the time hit to write tests is false economy. Every 10 minutes you save not writing tests can come back and cost you an hour, or maybe even a couple of days, debugging and maybe much more in lost customers when bugs make it to production.

    Or... a complete rewrite. If you have to redo most of it, it will likely be easier than retooling the original in situ. But, again, without a full functional spec or test suite or both, this will bite you hard. Sometimes 10K lines of code can be compressed to a few hundred with judicious application of the stars of the CPAN but that assumes you know exactly what you're doing and what the code is doing. Good luck and come back often with technical questions if you've got them. Many monks here can pull apart seeming Gordian knots easily.

Re: Reading Someone's Program
by Fletch (Bishop) on May 17, 2011 at 14:09 UTC

    Take off and nuke the site from orbit. It's the only way to be sure.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Reading Someone's Program
by CountZero (Bishop) on May 18, 2011 at 12:18 UTC
    This is a matter of "Fast, Good and Cheap -- choose any two".

    You cannot completely modify to new requirements and/or"modernize" it AND do it fast AND do it good, all at the same time.

    Depending on how extensive your modifications will be to answer the new requirements, a total "modern" rewrite may actually be easier.

    The fact that there are no tests available is a major problem.

    In any case, the first thing to do is write these tests. Without tests you will be actually navigating at night in dense fogs through unchartered waters and with no radar! Without tests you cannot be certain that what you wrote is not broken.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Reading Someone's Program
by eff_i_g (Curate) on May 17, 2011 at 14:53 UTC
    If the flow is murky log it by hooking the subs. I've had success with object creation/destruction in the aforementioned post. I've also found Aspect's before handy in recent times.
Re: Reading Someone's Program
by anonymized user 468275 (Curate) on May 17, 2011 at 15:10 UTC
    For my money, tux's answer is very good! In addition, try to reverse engineer the script into a rough hand-drawn flow diagram and insert any "chapter heading" style comments needed to express that diagram into the code before doing any modifying - the danger being addressed here is losing the functional to code tracking of what is being modified.

    One world, one people

Re: Reading Someone's Program
by sundialsvc4 (Abbot) on May 18, 2011 at 19:33 UTC

    I am in the wretched thick of just such a project right now.   The code is horrid.   One key practice for me is to make one code change at a time and to do it in a (git ...) separate branch.   This makes parallel sets of changes which are more-or-less tagged to why I made them.   I am also keeping a “running log” – a diary – of everything that I am doing, and I’m making the entire team do the same thing.

    The “Dealing Effectively” book, mentioned earlier, is one that of course I have looked at, but, having looked at it, didn’t buy.   I felt that it might be “the cat’s meow” if you happened to have stumbled upon a bunch of object-oriented code that just wasn’t quite up to snuff, but it had very little practical advice to offer with regard to the large mass of existing (true “legacy”) code that wasn’t built that way.

    Be wary of “change for the sake of change,” or what a former colleague of mine once called, “making it ‘–er.’”   You need to familiarize yourself with the code very thoroughly, and then consider what is the least intrusive set of changes that must be made in order to satisfy the new requirement.   Sometimes that isn’t the right approach:   sometimes the thing is so near dead that you have to grab the ol’ defrib paddles and shout, “Clear!”   But just remember that, if you blast the thing apart, you still have to put it all back together and send it running down the road at sixty miles an hour ...