31
Clean Code Hendrik Van Belleghem Belgian Perl Workshop 2007

Cleancode

Embed Size (px)

DESCRIPTION

Slides for talk on Clean Code given at the 2007 Belgian Perl Workshop. Reference: Damian Conways Perl Best Practices

Citation preview

Page 1: Cleancode

Clean CodeClean Code

Hendrik Van Belleghem

Belgian Perl Workshop 2007

Hendrik Van Belleghem

Belgian Perl Workshop 2007

Page 2: Cleancode

It’s all Bruces fault!

Page 3: Cleancode

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!

Page 4: Cleancode

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

Page 5: Cleancode

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

Page 6: Cleancode

Acme::Metasyntactic?Acme::Metasyntactic?

It’s all BooK’s fault!

Page 7: Cleancode

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

Page 8: Cleancode

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”; }

Page 9: Cleancode

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”;

}

Page 10: Cleancode

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

Page 11: Cleancode

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();

}

Page 12: Cleancode

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

Page 13: Cleancode

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,..

Page 14: Cleancode

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??

Page 15: Cleancode

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 $!;

Page 16: Cleancode

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

Page 17: Cleancode

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

Page 18: Cleancode

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);

Page 19: Cleancode

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

Page 20: Cleancode

AutoloadAutoload

Inheritence precedence? Inheritence precedence?

Catch all method

Page 21: Cleancode

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!

Page 22: Cleancode

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!

Page 23: Cleancode

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

Page 24: Cleancode

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

Page 25: Cleancode

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

Page 26: Cleancode

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

Page 27: Cleancode

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;

Page 28: Cleancode

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)

Page 29: Cleancode

Perl::CriticPerl::Critic As website : http://perlcritic.com As website : http://perlcritic.com

Page 30: Cleancode

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

Page 31: Cleancode

Thank you!Thank you!

どうもありがとうミスターロボット

(domo arigato, Mr Roboto)

どうもありがとうミスターロボット

(domo arigato, Mr Roboto)