I arrived late! Stupid work! :) feeling good != behaving well they rarely go together don't just program to feel good, you'll piss someone off these are just a set of guidelines to help combat Intuitive Programmer syndrome they are not unbreakable coding is collaborative; so is developing a coding style these rules are just a starting point. once you have the rules, you HAVE TO STICK TO IT giving up intuitive programming is like giving up smoking... crack flagellate transgressors! the style you choose DOESNT MATTER all are equally false it doesn't matter what you choose, as long as you choose SOMETHING then use it. possibly via automation (explanation of K&R) If you don't like K&R, that's fine. We need /someone/ to be wrong. If you code BSD style, you probably won't go to hell. You will if you do this: my @names = ( 1, 2, 3 ) ; "When Moses came down the mountain with the tablets --- and you can go to Jerusalem and look at them --- they used four-column tabs. That's what God wanted." align thing vertically; the required spaces will not fill up your hdd and prevent you from storing mp3s debugging is only required because you enbugged your code. try to avoid that by writing your code in a manner that helps prevent bugs! your code should be instantly understandable. IPS is about optimizing to write code. Instead, we should optimize not just to read, but to comprehend. Use whitespace, both vertical and horizontal, liberally. naming is closely related to layout. pick names that are readable don't useCapsLikeThisBecauseTheyAreHardToRead use_underscores_that_look_like spaces if you must abbreviate identifiers: abbr idents by pref nt by rmvng vwls name hashes in singular and arrays in plural you usually look up one value in a hash you usually use the array as a list (if you DO use an array as a lookup table, use the singular) use grammatical templates when forming identifiers (huh?) "If I don't have to write a comment, I win." for packages: Abstract_noun::Adjective Abstract_noun::Adjective::Adjective for subroutines: verb_noun verb_noun_preposition verb_noun_participle verb_adjective_noun for variables noun adjective_noun - better, usually special case: subs or vars as a bool name those for the predicate they test people overuse the "punctuation variables" like $/ and $| and so on don't use package variables either if you're FORCED to use one by a package that does, localize it where needed (remember that local will reset, not copy, the previous value) be very careful when modifying $_ fewer lines is fewer places for bugs to hide C is your natural enemy it hurts you it makes you have to think, and that's just wrong if a sub only modifies its argument, it probably has no return croak if used in non-void context "if you use it to assign, you probably have mental problems, and the correct solution is for me to kill you" avoid statement-scoped control structures (reverse if, etc) if you need to add complexity, you need to turn it around if you need to turn it around later, why not start out with it that way? avoid three-part for (duh) avoid subscripting in loops unless you absolutely need the indices iterate values, not indices look at Lexical::Alias -- OOOOOH use explicit named lexicals for C ... except if you use $_ ... and don't EVER leave off the C prefer C to C for generating new list from old prefer C to C for transforming a list in place use tabular ternaries cascade ?: instead of if's my $salute = $name eq $EMPTY_STR ? "Customer" : $name =~ m/\Afoo(...)\Z/x ? $1 : $name =~ m/\A(bar)(...)\Z/x ? $2 : $name; ; you can't forget the trailing "else" in a ternary development programmers hate it maintenance programmers love it eases the job of the maintenance programmer, whose job is to figure out "WTF was this guy thinking??" include both prose and examples -- but the prose needs to be boring and easy to understand include a list of acknowledgements. if people know their name will get listed if they wrote a patch, they're more likely to write a patch you are not allowed to cut and paste your code, but we'll let you cut and paste docs use =for sections comments for larger discussions comments are love letters that you send to your future self comment anything that has puzzled or tricked you ...when developing ...when maintaining ...that you don't understand (tea time!) use built-ins. more people use them. they're more optimized and more debugged always use BLOCK and not EXPR in map and grep use non-built-in built-ins, too: Scalar::Util, List::Util, etc always unpack @_, don't use $_[n] ...unless you just use @_ as a list of data use named arguments for $ARGC > n the only time to mix named and positional parameters is if the first param is the direct object and then comes a {} of options prototypes? just don't! they're too cool. "When your brain tells you 'it will be cool' it probably will not be cool." It might be a little more tedious and a little less cool, but it will just /work/ later. Always return with an explicit return. You will never accidentally return some random statement. Always return scalar. Don't use bareword filehandles. Use lexical filehandles instead. open my $fh, '<', $filename or croak $OS_ERROR; If you're using old perl, you can just localize the glob of the filehandle, but that's ugly: local *RECORDS; open RECORDS, '<', $filename or croak $OS_ERROR; Always use three-argument open. Man, I hope everyone listens to this suggestion! If taking input from a terminal, always prompt. (remember -t) Consider using IO::Prompt. (It's still not released. I AM SHOCKED.) Regular expression best practices could be an entire book -- and it wouldn't be Friedl. (It's a good book, but is about /all/ practices.) Always use /x ...and take advantage of it. Make your regex (which is code, after all) readable. Format and comment them. Always use /m and /s. /m -- ^ and $ now only refer to end/start of LINE (not string) use \A and \Z if you need SOS or EOS /s -- makes . match a newline, like anything else if you need everything but newline use /[^\n]/ So: always use /xms Consider using Regexp::Auto. (It's still not released. I AM SHOCKED.) Only use (...) when you're capturing something you're going to USE! Otherwise, use (?:...) -- it will save you from wondering where you were using the captures. always "name" any match values. Don't work with $1 and $2 and so on, assign the result of the listy contex'd match to a list of vars. ($foo, $bar) = $string =~ /(..)..(..)/xms; build up complex regexps from smaller pieces (I do this in Parse::IRCLog) look at Readonly instead of constant Avoid common alternations; use an (pre|suf|in)fix. Otherwise, it tries to match the common part over and over. Use (?>...) to avoid useless backtracking. Effective and maintainable error handling is the key to creating robust software. Prefer throwing exceptions over special return values. They don't need to be checked, because they'll propagate up. Return values need to be inspected. Always croak, never die. It shows them where things went wrong in /their/ code, not yours. Compose error messages that can be understood by the user. Make them meaningful. Modules and code re-use are great. Design the interface (the examples) first. Don't use v-strings. use version.pm if available for you Have a standard module template. (Module::Starter !) don't assume warning-free compilation means correctness; /testing/ promotes correctness be conscious of what you do: not just design, but construction!