Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Clean Code Hendrik Van Belleghem Belgian Perl Workshop 2007
It’s all Bruces fault!
Obviously? Pragmas warnings strict subs  : no barewords! refs  : no symbolic references! vars  : no undeclared variables!
Obviously? Variable names Variable names should be Short but not too short $i, $a, $o Unambiguous $i, $data, $line
Obviously? Variable names Variable names should definitely not be generated by Acme::MetaSyntactic: $thwacke   # batman $flrbbbbb  # batman $bondelschwaartz   #pynchon $ununquadium  # elements
Acme::Metasyntactic? It’s all BooK’s fault!
Obviously? Variable names Scalars are single $item Hashes and arrays are plural @items Mark booleans with test $found_match Add reference prefix/suffix $item_ref
Braces.. bad? Array definition my @list =  ( ‘larry’,  ‘ damian’ ); Any other block? for my $coder ( @list )  { print “hi $coder”; }
Braces..good? Array definition my @list = ( ‘ larry’, ‘ damian’ ); Any other block? for my $coder ( @list ) { print “hi $coder”;  }
Stay away from $_ $_ as default argument? -X, abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, exp, glob, hex, int, lc, lcfirst, length, log, lstat, oct , ord, pos, print, quotemeta, readlink, ref, require, reverse, rmdir, sin, split, sqrt, stat, study, uc, ucfirst, unlink Implicit use m//, s///, y/// for(), map {}, grep {}, while(<>) default input and pattern matching space
Postfix if buy(&quot;secret lair&quot;) and buy(&quot;sharks with lasers&quot;)  and $mini_me = clone() if $goal eq &quot;world domination&quot;; if ($goal eq “world domination”) { buy(“secret lair”);  buy(“sharks with lasers”); $mini_me = clone(); }
C style loops for (my $slide = 1; $slide < 25 ; $slide++) { present($slide); } for my $slide (1..25) { present($slide); } Cleaner Easier to read
POD Put POD in the source file.. At the end Check your POD! Podchecker Use POD templates & stubs NAME, VERSION, SYNOPSIS,..
String eval is bad Don’t overuse eval.. Period String eval is recompiled on execution Use block instead Are you taint-checking??
Filehandles Bareword filehandles Cannot be localized Passing it to a sub? Try typeglobs Better: indirect filehandles From 5.6 onwards open my $filehandle, ”<filename” or die $!;
Regexp::Common IP addresses? $ip =~ /$RE{net}{IPv4}/ MAC addresses? $ip =~ /$RE{net}{MAC}/ Credit cards $number =~ /$RE{zip}{VISA}/ For all your extraordinary regexp needs
Regexp::Common? It’s all Abigails fault! Dutch Tall Strapping hunk of  manhood For all your extraordinary regexp needs
Regexp Delimiters Question.. What does this do? harry s truman was the 33rd u.s. president; harry s |ruman was |he 33rd u.s. presiden|; harry($string =~ s{ruman was }{he 33rd u.s. presiden}xms);
Regexp Keep it simple! $foo =~ s{foo}{bar}g; $html =~ s/<(?:[^>'&quot;]*|(['&quot;]).*?)*>//gsx Add comments to big Regexp chunks Use    and    instead of  $  and  ^ s{ <  # opening angle bracket (?:  # Non-backreffing grouping paren [^>'&quot;] *  # 0 or more things that are neither > nor ' nor &quot; |  #  or else &quot;.*?&quot;  # a section between double quotes (stingy match) |  #  or else '.*?'  # a section between single quotes (stingy match) ) +  #  all occurring one or more times >  # closing angle bracket }{}gsx;  # replace with nothing, i.e. delete
Autoload Inheritence precedence? Catch all method
Refactoring Original code Duplicated code Move to subroutines Duplicated subroutines Move to packages No overkill!
Tests Write tests first Test::Simple & Test::More Test for failures Test the obvious & not so obvious Find a bug? Write a test!
Version control Multiple developers Undo Generate patches Merging/branching CVS, Subversion, RCS, Perforce, BitKeeper, git
Format Compile time definition No runtime changes Except with eval Global variables only Output to named filehandle
Tie Unknown magic Unpredictable behavior Eg: Tie::Scalar::RestrictUpdates limits changes Slow Change variable behavior through code
Perl::Critic As Module As command line tool As website : http://perlcritic.com DIY Configurable
Perl::Critic As Module use Perl::Critic; my $file = shift; my $critic = Perl::Critic->new(); my @violations = $critic->critique($file); print @violations;
Perl::Critic As command line tool lenore:~$ perlcritic -stern strict.pm  Code before strictures are enabled at line 3, column 1.  See page 429 of PBP.  (Severity: 5) Code before warnings are enabled at line 3, column 1.  See page 431 of PBP.  (Severity: 4) Always unpack @_ first at line 11, column 1.  See page 178 of PBP.  (Severity: 4) Subroutine does not end with &quot;return&quot; at line 11, column 1.  See page 197 of PBP.  (Severity: 4) Always unpack @_ first at line 27, column 1.  See page 178 of PBP.  (Severity: 4) Subroutine does not end with &quot;return&quot; at line 27, column 1.  See page 197 of PBP.  (Severity: 4) Always unpack @_ first at line 32, column 1.  See page 178 of PBP.  (Severity: 4) Subroutine does not end with &quot;return&quot; at line 32, column 1.  See page 197 of PBP.  (Severity: 4)
Perl::Critic As website : http://perlcritic.com
Perl::Critic As Module As command line tool As website : http://perlcritic.com DIY Lots of policies Configurable
Thank you! どうもありがとうミスターロボット (domo arigato, Mr Roboto)

More Related Content

Cleancode

  • 1. Clean Code Hendrik Van Belleghem Belgian Perl Workshop 2007
  • 3. Obviously? Pragmas warnings strict subs : no barewords! refs : no symbolic references! vars : no undeclared variables!
  • 4. Obviously? Variable names Variable names should be Short but not too short $i, $a, $o Unambiguous $i, $data, $line
  • 5. Obviously? Variable names Variable names should definitely not be generated by Acme::MetaSyntactic: $thwacke # batman $flrbbbbb # batman $bondelschwaartz #pynchon $ununquadium # elements
  • 7. Obviously? Variable names Scalars are single $item Hashes and arrays are plural @items Mark booleans with test $found_match Add reference prefix/suffix $item_ref
  • 8. Braces.. bad? Array definition my @list = ( ‘larry’, ‘ damian’ ); Any other block? for my $coder ( @list ) { print “hi $coder”; }
  • 9. Braces..good? Array definition my @list = ( ‘ larry’, ‘ damian’ ); Any other block? for my $coder ( @list ) { print “hi $coder”; }
  • 10. Stay away from $_ $_ as default argument? -X, abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, exp, glob, hex, int, lc, lcfirst, length, log, lstat, oct , ord, pos, print, quotemeta, readlink, ref, require, reverse, rmdir, sin, split, sqrt, stat, study, uc, ucfirst, unlink Implicit use m//, s///, y/// for(), map {}, grep {}, while(<>) default input and pattern matching space
  • 11. Postfix if buy(&quot;secret lair&quot;) and buy(&quot;sharks with lasers&quot;) and $mini_me = clone() if $goal eq &quot;world domination&quot;; if ($goal eq “world domination”) { buy(“secret lair”); buy(“sharks with lasers”); $mini_me = clone(); }
  • 12. C style loops for (my $slide = 1; $slide < 25 ; $slide++) { present($slide); } for my $slide (1..25) { present($slide); } Cleaner Easier to read
  • 13. POD Put POD in the source file.. At the end Check your POD! Podchecker Use POD templates & stubs NAME, VERSION, SYNOPSIS,..
  • 14. String eval is bad Don’t overuse eval.. Period String eval is recompiled on execution Use block instead Are you taint-checking??
  • 15. Filehandles Bareword filehandles Cannot be localized Passing it to a sub? Try typeglobs Better: indirect filehandles From 5.6 onwards open my $filehandle, ”<filename” or die $!;
  • 16. Regexp::Common IP addresses? $ip =~ /$RE{net}{IPv4}/ MAC addresses? $ip =~ /$RE{net}{MAC}/ Credit cards $number =~ /$RE{zip}{VISA}/ For all your extraordinary regexp needs
  • 17. Regexp::Common? It’s all Abigails fault! Dutch Tall Strapping hunk of manhood For all your extraordinary regexp needs
  • 18. Regexp Delimiters Question.. What does this do? harry s truman was the 33rd u.s. president; harry s |ruman was |he 33rd u.s. presiden|; harry($string =~ s{ruman was }{he 33rd u.s. presiden}xms);
  • 19. Regexp Keep it simple! $foo =~ s{foo}{bar}g; $html =~ s/<(?:[^>'&quot;]*|(['&quot;]).*?)*>//gsx Add comments to big Regexp chunks Use and instead of $ and ^ s{ < # opening angle bracket (?: # Non-backreffing grouping paren [^>'&quot;] * # 0 or more things that are neither > nor ' nor &quot; | # or else &quot;.*?&quot; # a section between double quotes (stingy match) | # or else '.*?' # a section between single quotes (stingy match) ) + # all occurring one or more times > # closing angle bracket }{}gsx; # replace with nothing, i.e. delete
  • 21. Refactoring Original code Duplicated code Move to subroutines Duplicated subroutines Move to packages No overkill!
  • 22. Tests Write tests first Test::Simple & Test::More Test for failures Test the obvious & not so obvious Find a bug? Write a test!
  • 23. Version control Multiple developers Undo Generate patches Merging/branching CVS, Subversion, RCS, Perforce, BitKeeper, git
  • 24. Format Compile time definition No runtime changes Except with eval Global variables only Output to named filehandle
  • 25. Tie Unknown magic Unpredictable behavior Eg: Tie::Scalar::RestrictUpdates limits changes Slow Change variable behavior through code
  • 26. Perl::Critic As Module As command line tool As website : http://perlcritic.com DIY Configurable
  • 27. Perl::Critic As Module use Perl::Critic; my $file = shift; my $critic = Perl::Critic->new(); my @violations = $critic->critique($file); print @violations;
  • 28. Perl::Critic As command line tool lenore:~$ perlcritic -stern strict.pm Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5) Code before warnings are enabled at line 3, column 1. See page 431 of PBP. (Severity: 4) Always unpack @_ first at line 11, column 1. See page 178 of PBP. (Severity: 4) Subroutine does not end with &quot;return&quot; at line 11, column 1. See page 197 of PBP. (Severity: 4) Always unpack @_ first at line 27, column 1. See page 178 of PBP. (Severity: 4) Subroutine does not end with &quot;return&quot; at line 27, column 1. See page 197 of PBP. (Severity: 4) Always unpack @_ first at line 32, column 1. See page 178 of PBP. (Severity: 4) Subroutine does not end with &quot;return&quot; at line 32, column 1. See page 197 of PBP. (Severity: 4)
  • 29. Perl::Critic As website : http://perlcritic.com
  • 30. Perl::Critic As Module As command line tool As website : http://perlcritic.com DIY Lots of policies Configurable