From: short <> Date: Sun, 17 Nov 2002 10:07:00 +0000 (+0000) Subject: first release X-Git-Tag: bp_liverpm~90 X-Git-Url: https://git.jankratochvil.net/?p=nethome.git;a=commitdiff_plain;h=ff7745dd3af42c6a4e18c9dae402d32c02273d88 first release --- diff --git a/src/Perl-Style b/src/Perl-Style new file mode 100644 index 0000000..10fe111 --- /dev/null +++ b/src/Perl-Style @@ -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() modifies $_ without its localization! Needed everywhere: +! # local $_; + while () { + 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.)