perlmeditation tilly As the title says, this is in no particular order, a number of random points about programming that I think are of exceptional importance. <readmore> <ol> <li> The most cost-effective method of testing is code reviews. This is true even <i>before</i> you count in benefits in terms of knowledge transfer etc. <li> The bug is probably in your code. Failing that it is probably in something that changed recently. <li> You are using version control software and have backups, aren't you? <li> The hardest class of bugs, and one of the most common causes of failure for large projectgs lies in keeping track of interactions at interfaces. This has been known since the 70's and [id://22507]. <li> Most software projects fail. The odds of failure rise sharply with how hard it is for one person to keep track of what is going on. The more people you have, and the longer it is expected to take, the worse your odds are. <li> When we start a project we inevitably do not know as much as we will learn. Therefore we will make decisions that in hindsight would be better being changed. Plan ahead. If your interfaces hide information (as recommended in references like [|Code Complete]) then you are going to have an easier time in revisiting decisions. This will be even easier if you have a good set of [cpan://Test::Unit|unit tests] like the [|XP people] recommend. (Thanks [clemburg].) <li> Programming is about keeping track of ideas. How can you make this easier on yourself? <li> Have you thought through your boundary cases in detail? Methodically walk through your code and test them, you may be shocked... <li> One of the most common errors is to reverse the meaning of a flag. This is both an easy error to make, and is hard to catch in reviews. But name variables as yes/no questions and you will almost never make this mistake. Consider starting the name of your next flag with "is"... <li> Don't make an <b>ass</b> of yo<b>u</b> and <b>me</b>. <li> It is typically impossible to list all things that could go wrong. It is generally fairly easy to list conditions under which your code should behave correctly. This observation has enormous consequences for how you should validate user input... <li> The basic outline of a transaction is that you note that there is work to be done. create a private work area, work in it, and then when the work is complete you make it public. The really nice thing about thinking in terms of transactions is that virtually all failure situations are easy to handle, just log the issue, save your private space (directory etc) somewhere for later inspection, and abort the transaction. If you in addition make a habit of keeping track of work that needs to be done in a table and retry it periodically, you will be amazed at how the system tends to be robust in the face of unexpected problems. The relevance of these points might not sink in for you until the next time a complex sequence of steps breaks, leaving things in an inconsistent state... <li> It is likely that more truly innovative ideas have come out of play than serious professionalism. Luckily great software does not need to be particularly innovative. <li> That is a nice shiny wheel you just reinvented... <li> ...on the other hand the world needs more than one type of wheel... <li> ...but the best way to create a new wheel is generally to modify an existing one in unexpected ways. For instance though woodworking could have used a wheel earlier, they didn't get one until Tabitha Babbitt modified her spinning wheel into a circular saw (circa 1813 or so). <li> That which is not automated does not reliably happen. <li> Be sure you have error checks... <li> ...but will your messages make sense if things do go wrong? </ol> I know I missed plenty. So please add to the list.