Well ... some general thoughts on splitting up unknown code
Incremental strategy
- create your test suite first
- do little steps, and always test the result
- use a revision control system like git
- commit every change
- use branches for experiments
- once you found a previously untested bug expand your test suite and roll back
Prerequisites
Study and understand
==== Perl essentials
- strict and warnings
- my vs our variables,
- namespaces, scoping, blocks
- exporter
- constants
- warn and die
==== Tools and techniques
==== your application
- your data model ( database, configs)
- input and output
- avaliable doc
- stakeholders (users, contributers, maintainers) to ask
Analyze
- analyze the dependencies of your subs (x calls y calls z)
- analyze the shared variables
- try to visualize the dependencies in a graph
- the hierarchy should help identifying logical units (aka modules)
- use tools to help you analyze like B::Xref
- other tools like mentioned here: Searching for duplication in legacy code
- identify dead code (never called subs, out-commented trash)
Documentation
- once you understood a mechanism, write it down
- use Pod headers when possible
- normalize (beautify) your code with Perl::Tidy
- review your pod2html from time to time and fill gaps
Modularisation / Namespaces ?
- bundle subs into modules by functionality not technology (not all sql in one module, eg look at the TABLE names )
- require into the same namespace might be an easier intermediate step before learning to use exporter °
- modules normally require namespaces (packages)
- package variables in other modules need to be fully qualified when used outside $Pkg::var °
- same for Pkg::subs() °
- modules allow to export vars and subs when use d
- modules allow to pass and init shared variables when using import (like a database handle)
Object Oriented Programming
- logical modules are sometimes better OO classes
- check guides on "when OOP is better"
- indicator: if you have to pass around same arguments
- indicator: group of subs access always same global vars
- indicator: init() routines for globals are sometimes better ->new()
- easier to construct an object with encapsulated instance vars and class vars
- have a look at Moo before doing old style OOP
Improvement
- make your code more fault tolerant
- add argument checking to your subs
- rewrite many positional args into named args
- condense duplicated code into new functions
- limit the scope of vars and subs if possible
- give identifiers like variables meaningful names
- document your strategy for future maintainers
See Also
update
Expanded the OOP part
°) that's an intermediate step exporting and importing is much cleaner
²) As a rule of thumb from easier to better
- require files same namespace (NB: my-lexicals can't be shared)
- try to group connected subs into namespaces with package
- use module different namespaces => full qualified identifiers for shared data
- use module different namespaces => exporting and importing shared data
- use oo-class : shared data in instance/class-vars and methods, transport via constructor and setter/getters
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|