Layering/encapsulation and good API design are the keys to good programming.
Too much abstraction is as bad as too little.
Minimize code dependencies and specially temporal dependencies: I specially hate the case when you have an object that requires its methods to be called in a particular order and that is manipulated from different layers. Impossible to follow code!
If you have to write some complicated piece of code, try to hide it behind and easy to use API.
Code flow must be easy to follow.
Perl is a powerful and expressive language, don't be afraid to use it to its maximum.
Avoid code duplication. Don't copy&paste. Boilerplate is OK to a certain degree.
Make your subs/methods meaningful.
Try to avoid helper subs/methods with long lists of arguments.
Don't use an object when a simple hash or array will do.
Speed matters, scalability matters, memory usage matters, IO matters. Keep that in your mind while programming.
When breaking some of the previous rules, document it.
Check the validity of your input (specially when dealing with external input), refuse anything you don't know how to handle: Note that this does not go against the robutness principle, they are orthogonal concepts.
Write regular expressions as strict as possible.
Check for errors extensively. Don't ignore them.
Include internal consistence checks.
Add lots of debugging code so that you may be able to debug problems reported by others even when you are not able to reproduce them.
Depending on an external module needs a good justification.
use strict, use warnings, selectively disable them when required.
No TDD, it gets on the way of my iterative design/programming thinking process (but if it works for you I am OK with it).
Otherwise, testing is a very good thing.
Be consistent in your coding style.
And use a good editor that takes care of it for you: actually I don't care too much about cosmetics, as far as blocks are indented it is OK for me.
Finally, paraphrasing the great Salvor Hardin, "Never let your sense of best practices prevent you from doing what is right!"
I prefer to have two separate lists: one for general
programming practices, another for language-specific ones.
The general, language-independent list tends to be
the more important and interesting of the two IMHO.
Most language-specific items, such as
"start each file with use strict"
"use three-argument open and lexical file handles"
are easily detected by a tool, such as Perl::Critic.
The general list, OTOH, usually requires a human with
good taste to adjudicate.
Pray tell, how precisely does Python prevent you
from using bad variable names?
How does Python enforce good encapsulation?
How does Python detect methods and functions that are too long?
How does Python help you avoid poor coupling and
promote wise decomposition?
Does Python write good documentation for you?
Does Python require comprehensive testing?