first release
authorshort <>
Sun, 17 Nov 2002 10:07:00 +0000 (10:07 +0000)
committershort <>
Sun, 17 Nov 2002 10:07:00 +0000 (10:07 +0000)
src/Perl-Style [new file with mode: 0644]

diff --git a/src/Perl-Style b/src/Perl-Style
new file mode 100644 (file)
index 0000000..10fe111
--- /dev/null
@@ -0,0 +1,216 @@
+$Id$
+
+Important lines prefixed by '[!](?:(?!\s)| )'.
+General (non-Perl) lines prefixed by '[~](?:(?!\s)| )'.
+Perl general knowledge from docs prefixed by '[#](?:(?!\s)| )'.
+
+Perl-5.0+ header:
+!              #! /usr/bin/perl -w
+               #
+               #       $Id$
+
+               package My::Package::Name;
+!              use vars qw($VERSION);
+! #            $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
+!              use strict;
+               #use warnings;
+       * Note 'sprintf' hack to keep Perl MakeMaker numbering linear with CVS.
+       * Always using 'strict'/'warnings'
+       * Not sure if one has right to declare own non-CPAN-accepted package
+         name outside of 'My::' prefix, recently using always rather 'My::'
+
+Perl-5.6.0+ header:
+!      #! /usr/bin/perl
+       #
+       #       $Id$
+
+       package My::Package::Name;
+! #    our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
+!      use strict;
+!      use warnings;
+
+
+Header block for OO files and/or exporting files:
+       require My::Inherited1;
+       require My::Inherited2;
+       require Exporter;
+       use vars qw(@ISA @EXPORT);
+       @ISA=qw(My::Inherited1 My::Inherited2 Exporter);
+       @EXPORT=qw();
+
+Generally always rather 'require' than 'use'. Modules with non-conflicting
+naming are 'use'd (such as 'MIME::Base64' with &encode_base64 etc.).
+
+Method parenthesis:
+!      * Always given if no arguments are passed.
+!      * Always given for any object or class method calls.
+!      * Always given if the first arguments looks as bless()ed.
+       * docs/comments: 'method()' used for invocation, '&method' for reference
+!      * Always given for 'map', 'each' (commands-not methods from previous line)
+       * Trying to prevent if not neccessary
+!      * Usually needed for 'print' argument as its first arg already has '()'
+!      * Never using 'method_name blessed_object' syntax:
+               Dangerous:
+                       name blessed_object
+               interpreted as
+                       blessed_object->name()
+               instead of intended
+                       name(blessed_object)
+
+Always use named control variable for 'for my $var (...)' if the naming makes
+sense, leave the default '$_' instead of common names such as $i or $n.
+
+Function header:
+               # $first_arg,%$secondarg,@rest
+               sub function_name
+               {
+               my($class,first_arg,$secondarg,@rest)=@_;
+       * Comment-line suppressed if trivial.
+       * Comment-line written in the dereferencing operators order being used
+         for accessing elements.
+!      * Suicide imminent if '=@_' forgotten.
+       * Always used $class or $self for class-methods or object-methods.
+               * Usually not using (caller should call it manually):
+                       $self=$self->new() if !ref $self;
+!      * Never modifying @_ to keep perl debugger 'T' command happy
+       * Wanna use function prototypes (not yet) although I will never use
+         '\', '*' or '&' for the same reasons I would never use C++ '&' param.
+
+Not using: 'unless'(->'if !'), 'until'(->'while !'), 'foreach'(->'for').
+
+Always trying to use 'map' instead of 'for'. Nested 'map's are fined although
+$_ renaming is needed there:
+       map({
+!              my $whole_record=$_;
+               map({ $_+$whole_record->{"shift_value"}; } ($whole_record->{"list"}));
+               } @some_record_list)
+
+Always trying to place 'for'/'if'/'while' after the command (without block).
+       * Impossible if multiple modifiers needed (just one placed after):
+!              print "$_\n" for (0..5) if $do_print;
+       * Impossible if using variable declared in the modifier:
+!              print "$var\n" for my $var (@some_array);
+       * Sometimes even using for multiple commands under the control:
+                       do { print "kaboom"; return; } if $serious_problem;
+               do not use this as even 'print' can fail:
+                       print "kaboom" and return if $serious_problem;
+               (and it uses unclear precedence rules)
+
+OO constructor always named &new or &new_*.
+
+Utility functions without any OO sense do not use $class or $self.
+
+Rather referrencing rvalue than dereferrencing lvalue:
+               @{$ref->{"array"}}=(1,2,3);
+       never used, I like rather:
+               $ref->{"array"}=[1,2,3];
+
+Lists parenthesed where passed as 'list' argument:
+               map({ some_function_body; } listarg1,listarg2);
+       never used, I like rather:
+               map({ some_function_body; } (listarg1,listarg2));
+       * parentheses suppressed if simple '@array_name' is passed.
+
+Last command of block { } always suffixed by its ';'.
+
+String substitution used only for simple scalars, concatenation used otherwise:
+               print "total_crashes: $left or $maybe->{'crashes'}\n";
+       never used, I like rather:
+               print "total_crashes: $crashes or ".$maybe->{'crashes'}."\n";
+
+Conditional expressions 'a?b:c' usually use the same item
+       $record->{"field"}==5 ? 7 : $record->{"field"}+1
+can be nicely rewritten as:
+!      map(($_==5 ? 7 : $_+1),$record->{"field"})
+
+while(<HANDLE>) modifies $_ without its localization! Needed everywhere:
+! #    local $_;
+       while (<HANDLE>) {
+               some_commands;
+               }
+
+Never used barewords for hash keys, always quoted:
+               $hashref->{somekey}
+       never used, I like rather:
+!              $hashref->{"somekey"}
+as it can crash for some reseverd words used as 'somekey'.
+
+You cannot use positive-case substitution in list context:
+               @list=($user_wishes{"provide_arg"} && "real_arg");
+       does '@list=(undef()); @list==1; #YES' if !$user_wishes{"provide_arg"},
+       instead you must code the full ugly construction:
+!              @list=(!$user_wishes{"provide_arg"} ? () : ("real_arg"));
+
+~ Conditional-evaluation always shortcut optimized by providing the trivial case
+as the first one of two branches (even if such trivial branch has more source
+code letters to write).
+               @new_list=(!@list ? (list_is_empty(\@list)) : @list);
+       although sometimes the meaning of 'trivial case' can be subjective.
+
+# Private methods named as &_method (still must be called as _method()!).
+
+~ Value being prepared for return named 'r'.
+
+It may get handy to use:
+       confess if !wantarray() && 2<=@r;       # optional and sometimes not appropriate
+       return wantarray() ? @r : $r[0];
+
+Never using 'die' or 'warn', always 'confess' or 'cluck'
+(and never 'carp' or 'cloak'):
+       use Carp qw(cluck confess);
+
+Always local()ize file handle globref if not in package 'main':
+!      local *F;
+       do { open F,$_ or confess "$_: $!"; } for ("some_file");
+
+There are many ways to code 'C switch(){}', I use:
+                  if (cond1) {
+                       }
+               elsif (cond2) {
+                       }
+               else {
+                       }
+       although it is deprecated by Perl doc but they do not give much better
+       solutions. Some of them are restricted to single command body ('do {}'
+       needed) etc. if-elsif-else method would be shorter in the code if
+               } elsif (condX) {
+       indenting style is used.
+
+~ Function definitions ordered lower->higher to prevent pre-declarations.
+
+! For any non-trivial data structures it is essential to differentiate between:
+       scalar, list, array, hash, ref to scalar, ref to array, ref to hash
+
+Any missing trailing function parameters appear as undef().
+Any passed trailing undef()s can still be properly detected and interpreted:
+       scalar(@_) will still report the real number of parameters.
+       undef() is the real parameter.
+
+Perl is too damn slow during startup but it is blazingly fast when it runs.
+mod_perl prevents this startup overhead (present in standalone Perl CGIs).
+'Storable'-disk-dumped complex memory data structures are 10x larger in memory
+as reported by http://petamem.com .
+
+Curly-bracketing all subexpressions for dereferencign explicitely if not trivial:
+               my %rec=("x"=>["a\n","b\n"]);print @$rec{"x"};
+               print @$arrayref;
+       would not work as it would mean:
+               my %rec=("x"=>["a\n","b\n"]);print @{$rec}{"x"};
+               print @$arrayref;
+       , I like rather even if it would work without curly-bracketing:
+!              my %rec=("x"=>["a\n","b\n"]);print @{$rec{"x"}};
+               print @$arrayref;
+
+Declaration scope of 'my' in the non-sub{} file: Whole file inside one package.
+Declaration scope of 'my' in sub{}: Only this sub{}, not accessible by callees.
+Declaration scope of 'local': This sub{} and globally for all callees.
+       * Perfect for some nesting counters:
+               my $func_nest=0;
+               sub func
+               {
+               # automatically restored after exit from &func
+               local $func_nest=$func_nest+1;
+               }
+       * Built-in variables cannot be 'my' scoped, use 'local' instead
+Declaration scope of 'our'(5.6.0+) or 'use vars...': Global across packages.
+(These scoping rules are IMO simplified but works4me.)