View
8
Download
2
Category
Preview:
DESCRIPTION
Slides for talk on Clean Code given at the 2007 Belgian Perl Workshop. Reference: Damian Conways Perl Best Practices
Citation preview
Clean CodeClean Code
Hendrik Van Belleghem
Belgian Perl Workshop 2007
Hendrik Van Belleghem
Belgian Perl Workshop 2007
It’s all Bruces fault!
Obviously? PragmasObviously? Pragmas
warnings strict
subs : no barewords! refs : no symbolic references! vars : no undeclared variables!
warnings strict
subs : no barewords! refs : no symbolic references! vars : no undeclared variables!
Obviously? Variable namesObviously? Variable names
Variable names should be Short
but not too short $i, $a, $o
Unambiguous $i, $data, $line
Variable names should be Short
but not too short $i, $a, $o
Unambiguous $i, $data, $line
Obviously? Variable namesObviously? Variable names
Variable names should definitely not be generated by Acme::MetaSyntactic:
$thwacke # batman $flrbbbbb # batman $bondelschwaartz #pynchon $ununquadium # elements
Variable names should definitely not be generated by Acme::MetaSyntactic:
$thwacke # batman $flrbbbbb # batman $bondelschwaartz #pynchon $ununquadium # elements
Acme::Metasyntactic?Acme::Metasyntactic?
It’s all BooK’s fault!
Obviously? Variable namesObviously? Variable names
Scalars are single $item
Hashes and arrays are plural @items
Mark booleans with test $found_match
Add reference prefix/suffix $item_ref
Scalars are single $item
Hashes and arrays are plural @items
Mark booleans with test $found_match
Add reference prefix/suffix $item_ref
Braces.. bad?Braces.. bad?
Array definitionmy @list =
( ‘larry’,
‘damian’ );
Any other block?for my $coder ( @list )
{ print “hi $coder\n”; }
Array definitionmy @list =
( ‘larry’,
‘damian’ );
Any other block?for my $coder ( @list )
{ print “hi $coder\n”; }
Braces..good?Braces..good?
Array definitionmy @list = (
‘larry’,
‘damian’
);
Any other block?for my $coder ( @list ) {
print “hi $coder\n”;
}
Array definitionmy @list = (
‘larry’,
‘damian’
);
Any other block?for my $coder ( @list ) {
print “hi $coder\n”;
}
Stay away from $_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(<>)
$_ 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 ifPostfix if
buy("secret lair") and
buy("sharks with lasers")
and $mini_me = clone()
if $goal eq "world domination";
if ($goal eq “world domination”)
{ buy(“secret lair”);
buy(“sharks with lasers”);
$mini_me = clone();
}
buy("secret lair") and
buy("sharks with lasers")
and $mini_me = clone()
if $goal eq "world domination";
if ($goal eq “world domination”)
{ buy(“secret lair”);
buy(“sharks with lasers”);
$mini_me = clone();
}
C style loopsC style loops
for (my $slide = 1; $slide < 25 ; $slide++)
{ present($slide); }
for my $slide (1..25)
{ present($slide); }
Cleaner Easier to read
for (my $slide = 1; $slide < 25 ; $slide++)
{ present($slide); }
for my $slide (1..25)
{ present($slide); }
Cleaner Easier to read
PODPOD
Put POD in the source file.. At the end
Check your POD! Podchecker
Use POD templates & stubs NAME, VERSION, SYNOPSIS,..
Put POD in the source file.. At the end
Check your POD! Podchecker
Use POD templates & stubs NAME, VERSION, SYNOPSIS,..
String eval is badString eval is bad
Don’t overuse eval.. Period String eval is recompiled on execution
Use block instead
Are you taint-checking??
Don’t overuse eval.. Period String eval is recompiled on execution
Use block instead
Are you taint-checking??
FilehandlesFilehandles
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 $!;
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::CommonRegexp::Common
IP addresses?$ip =~ /$RE{net}{IPv4}/
MAC addresses?$ip =~ /$RE{net}{MAC}/
Credit cards$number =~ /$RE{zip}{VISA}/
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?Regexp::Common?For all your extraordinary regexp needs
It’s all Abigails fault! Dutch Tall Strapping hunk of
manhood
It’s all Abigails fault! Dutch Tall Strapping hunk of
manhood
Regexp DelimitersRegexp 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);
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);
RegexpRegexp
Keep it simple! $foo =~ s{foo}{bar}g; $html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsx
Add comments to big Regexp chunks
Use \A and \Z instead of $ and ^
Keep it simple! $foo =~ s{foo}{bar}g; $html =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gsx
Add comments to big Regexp chunks
Use \A and \Z instead of $ and ^
s{ < # opening angle bracket (?: # Non-backreffing grouping paren [^>'"] * # 0 or more things that are neither > nor ' nor " | # or else ".*?" # 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
AutoloadAutoload
Inheritence precedence? Inheritence precedence?
Catch all method
RefactoringRefactoring
Original code Duplicated code
Move to subroutines
Duplicated subroutines Move to packages
Original code Duplicated code
Move to subroutines
Duplicated subroutines Move to packages
No overkill!
TestsTests
Write tests first Test::Simple & Test::More Test for failures Test the obvious & not so obvious Find a bug? Write a test!
Write tests first Test::Simple & Test::More Test for failures Test the obvious & not so obvious Find a bug? Write a test!
Version controlVersion control
Multiple developers Undo Generate patches Merging/branching
CVS, Subversion, RCS, Perforce, BitKeeper, git
Multiple developers Undo Generate patches Merging/branching
CVS, Subversion, RCS, Perforce, BitKeeper, git
FormatFormat
Compile time definition No runtime changes
Except with eval
Global variables only Output to named filehandle
Compile time definition No runtime changes
Except with eval
Global variables only Output to named filehandle
TieTie
Unknown magic Unpredictable behavior Eg: Tie::Scalar::RestrictUpdates limits changes
Slow Change variable behavior through code
Unknown magic Unpredictable behavior Eg: Tie::Scalar::RestrictUpdates limits changes
Slow Change variable behavior through code
Perl::CriticPerl::Critic
As Module As command line tool As website : http://perlcritic.com
DIY Configurable
As Module As command line tool As website : http://perlcritic.com
DIY Configurable
Perl::CriticPerl::Critic
As Module
use Perl::Critic;my $file = shift;my $critic = Perl::Critic->new();my @violations = $critic->critique($file);print @violations;
As Module
use Perl::Critic;my $file = shift;my $critic = Perl::Critic->new();my @violations = $critic->critique($file);print @violations;
Perl::CriticPerl::Critic
As command line tool 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 "return" 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 "return" 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 "return" at line 32, column 1. See page 197 of PBP. (Severity: 4)
Perl::CriticPerl::Critic As website : http://perlcritic.com As website : http://perlcritic.com
Perl::CriticPerl::Critic As Module As command line tool As website : http://perlcritic.com
DIY Lots of policies
Configurable
As Module As command line tool As website : http://perlcritic.com
DIY Lots of policies
Configurable
Thank you!Thank you!
どうもありがとうミスターロボット
(domo arigato, Mr Roboto)
どうもありがとうミスターロボット
(domo arigato, Mr Roboto)
Recommended