Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

This is a really difficult question to answer well, but I'll leap in anyway.

The best way to learn your own guidelines is to read other people's code. You will never stumble onto a number of useful rules of thumb staring at your own code. Look at how other people do things, and copy them.

Some rules of thumb I have come up with. (Later: the more I reread this, the more I can see all sorts of exceptions and qualifiers). Rules are meant to be broken, but of course you have to know the rules to be aware that you're breaking them.

The division between parent code and child subroutine should be natural. It should seem... elegant. If it feels klugey... it probably is! Again, read other people's code. Doesn't have to be good. Read some bad code, and criticise it. Think how you would do it differently.

Anyway, here are some things to think about:

Multi-modal subroutines

are a bad idea. If you're passing a mode parameter which is immediately inspected by the subroutine in order for it to decide how to proceed then you're probably travelling down the wrong path.

A routine should do one thing, and one thing only. Once it has been read, a person should not have to go back to it time and again when reading other parts of the code.

If you can't escape modality, include some good debug harnessing, so that the program flow can be traced by setting various levels of debug constants.

Factorisation

If you are performing functionality in two different parts of a script, then factor it into a subroutine. This often crops up when you are grovelling through data. Any time you are reading line by line (or paragraph, XML element or whatever) and remembering something about the previous line to see whether the current line indicates a change, you will have a block of code inside an if statement that performs the summary about the previous batch of lines. When you finally exit out of the read loop, you shall probably need to call that code block one again outside the loop to deal with the last batch of lines.

Locality of reference

A subroutine should have its entire context defined by the parameters passed to it. It should not rely on global variables. I break this rule all the time, although with the following context: it's okay for a subroutine to read global variables, but it should never modify them. If you're passing more than five parameters to a subroutine there's probably something bad happening to your code. Maybe some of that context would be better off wrapped up in a little object capable of maintaining its own sense of integrity.

Input and Output

Should be managed at the highest level of the code. Eschew little subroutines that call print themselves. Retain internal representations as long as possible, by passing back scalars, hashes or whatever, and have the parent perform the output instead.


--
g r i n d e r

In reply to Re: To sub or not to sub, that is the question? by grinder
in thread To sub or not to sub, that is the question? by tachyon

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others taking refuge in the Monastery: (7)
    As of 2020-01-23 13:21 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?
      Notices?