introduction to writing readable and maintainable perl

36
Introduction to writing readable and maintainable Perl Or Perl Best Practices: The Best Bits Or Perl is more readable than Java! Or Your code is bad and you should feel bad

Upload: alex-balhatchet

Post on 10-May-2015

7.235 views

Category:

Documents


3 download

DESCRIPTION

An introduction to writing readable Perl code, for people who write Perl that other people may want to read. Covers the most important lessons from Perl Best Practices, and ends by showing how to use Perl::Critic to test that you are meeting the standards set out.Given at FOSDEM 2011

TRANSCRIPT

Page 1: Introduction to writing readable and maintainable Perl

Introduction to writing readable and maintainable Perl

Or

Perl Best Practices: The Best Bits

Or

Perl is more readable than Java!

Or

Your code is bad and you should feel bad

Page 2: Introduction to writing readable and maintainable Perl

Who Am I?

Working for a small company

~5 years of code582 modulesLots of legacy codeAll Perl

Alex Balhatchet

Super Nerd since 1985Perl Hacker since 2002Londoner since 2004Paid Perl Hacker since 2006

Page 3: Introduction to writing readable and maintainable Perl

Who are you guys?

Perl Oldies?Perl Newbies?Curious non-Perl types?

Page 4: Introduction to writing readable and maintainable Perl

I'm here to convince you that Perl can be readable!

my @files = @ARGV;

foreach my $file (@files) { open(my $fh, '<', $file);

while (my $line = readline($fh)) { print $line; }

close($fh);}

Page 5: Introduction to writing readable and maintainable Perl

Summary

PragmasCPANBest Perl Best PracticesLegacy CodePerl::Critic & Perl::TidyQuestions

Page 6: Introduction to writing readable and maintainable Perl

Pragmas

Page 7: Introduction to writing readable and maintainable Perl

Always use strict

use strict makes your code safer

requires that all variables are declared with "my", "our", etc.- stops you from making typos in variable namesstops you from using symbolic (string) references- stops you from writing terrible terrible codedoes not allow non-subroutine barewords- stops you making typos in subroutine calls

Page 8: Introduction to writing readable and maintainable Perl

...and use warnings

use warnings ensures that odd things do not silently try to "do what you mean."

print(undef) - uninitialized value in print() 1 + "bananas" - non-numeric value in addition %hash = (1, 2, 3); - odd number of elements in hash

Page 9: Introduction to writing readable and maintainable Perl

Other Useful Pragmas

# make open() and others die on erroruse autodie;

# enable say(), given(), state, etc.use feature ':5.10'; # enable all of themuse feature 'say'; # enable one at a time

# make warnings throw exceptionsuse warnings FATAL => 'all';

Page 10: Introduction to writing readable and maintainable Perl

CPAN

Page 11: Introduction to writing readable and maintainable Perl

The CPAN

The CPAN is by far the best thing about Perl.

http://search.cpan.org

90,000 modules! Using CPAN modules means your code gets maintained, bug-fixed and optimized for you!

Page 12: Introduction to writing readable and maintainable Perl

Picking CPAN Modules

With 90,000 modules it can be difficult to pick the right one...

Which is the right one for the job?

Page 13: Introduction to writing readable and maintainable Perl

Picking CPAN Modules

Use the CPAN Testers reports, rt bug tracker, and Reviews. Every Distribution will have these!http://search.cpan.org/dist/Data-Dumper/

CPAN Testers: PASS (561) FAIL (8) UNKNOWN (4) Rating: (9 Reviews)

Page 14: Introduction to writing readable and maintainable Perl

Picking CPAN Modules

The Task::Kensho CPAN module is a documentation-and-dependencies-only distribution which can be used as a recommended modules list.Some highlights are...App::cpanminus, Test::Most, Try::Tiny, Devel::NYTProf, Perl::Critic, DateTime, Config::General, and App::Ack It's a great starting point!

Page 15: Introduction to writing readable and maintainable Perl

Best Perl Best Practices

Page 16: Introduction to writing readable and maintainable Perl

Code in paragraphs

Code which is written in paragraphs is much more readable.

# get ready...read_commandline_arguments(); init(); # actual work here...do_stuff();

# output...format_output();output_stuff();

Page 17: Introduction to writing readable and maintainable Perl

Throw Exceptions

Modern programming wisdom gives us many reasons Exceptions win out over error codes.

Impossible to ignoreFunctions don't have to try to return two valuesSeparate exceptional from non-exceptional cases

Page 18: Introduction to writing readable and maintainable Perl

Throw Exceptions

Perl implements Exceptions with strings and die(). die "Exception!"; You can use eval() to catch them, but the Try::Tiny module gives us Java-style try/catch keywords which are much nicer. try { stuff();}catch { # exception is in a lexically scoped $_ variable}

Page 19: Introduction to writing readable and maintainable Perl

Use builtins

Builtins in Perl are sensible and readable, especially when your editor has decent syntax highlighting.

Perl is excellent at string manipulation and dealing with lists. Use it to its full potential.

Perl's builtins have well defined names and behaviours, learn to love them.

Page 20: Introduction to writing readable and maintainable Perl

Use builtins

while (my $line = readline($fh)) { # ...} warn "warning! something's weird";

while (my $line = <$fh>) { # ...}

print STDERR "is this a warning? who knows?!";

Page 21: Introduction to writing readable and maintainable Perl

Use builtins

if (defined $value){ # stuff...}

my @files = glob("*.txt");

if ($value){ # stuff...}

my @files = <*.txt>;

Page 22: Introduction to writing readable and maintainable Perl

Use honorary builtins

There are a number of "honorary builtins" which are exported by core modules.

use Scalar::Util qw(looks_like_number openhandle);

use List::Util qw(first max min shuffle sum);

use List::MoreUtils qw(any all none uniq apply);

Page 23: Introduction to writing readable and maintainable Perl

Avoid overly confusing idioms and cleverness

Perl lets you write code however you want.

TIMTOWTDI - There is more than one way to do it.

A big part of writing readable Perl is about admitting that some of the ways to do it suck!

Page 24: Introduction to writing readable and maintainable Perl

Avoid overly confusing idioms and cleverness

What does this do?

my $result = [ $result1 => $result2 ] ->[ $result2 <= $result1 ];

Page 25: Introduction to writing readable and maintainable Perl

Avoid overly confusing idioms and cleverness

Maybe it's more obvious like this... use List::Util qw(min); my $result = min($result1, $result2);

Page 26: Introduction to writing readable and maintainable Perl

Legacy Code

Page 27: Introduction to writing readable and maintainable Perl

Be consistent with existing code

This is an important rule, because it often contradicts all the others I've mentioned:

When dealing with an existing code base, be consistent.

Page 28: Introduction to writing readable and maintainable Perl

Perl::Critic & Perl::Tidy

Page 29: Introduction to writing readable and maintainable Perl

Be consistent with existing code

If you change the existing code...

Make sure there are testsMake sure there are good testsChange the whole file so that consistency is maintainedCommit your changes to your VCS as a whole, without any other changes!

Page 30: Introduction to writing readable and maintainable Perl

Perl::Critic

Perl::Critic, and its binary friend perlcritic, is a tool which will tell you what is wrong with your Perl code. % perlcritic my_script.pl

Page 31: Introduction to writing readable and maintainable Perl

Perl::Critic

#!/usr/bin/perl

use feature 'say';

open(IN, $0);while (<IN>) { chomp; for (split //, $_) { $letters{$_}++; }}

foreach (sort keys %letters) { say "$_\t$letters{$_}";}

close(IN);

How many mistakes can you spot?

Page 32: Introduction to writing readable and maintainable Perl

Perl::Critic

% perlcritic --verbose 11 bad_perl.pl

Bareword file handle opened at line 3, near 'open(IN, $0);'. InputOutput::ProhibitBarewordFileHandles (Severity: 5) Using bareword symbols to refer to file handles is particularly evil because they are global, and you have no idea if that symbol already points to some other file handle. You can mitigate some of that risk by......

Contains the full Perl Best Practices text!!

Page 33: Introduction to writing readable and maintainable Perl

Perl::Tidy

Perl::Tidy, and perltidy, is a tool for automatically tidying up Perl code to make it more readable.

It can...

convert tabs into spacesrestrict lines to 80 charactersautomatically line up "=>" characters in hashes and ","'s in listsadd semi-colons where they belongun-cuddle elses

The perltidyrc file listed in Perl Best Practices can be found here:

http://www.perlmonks.org/?node_id=485885

Page 34: Introduction to writing readable and maintainable Perl

Questions etc.

Page 35: Introduction to writing readable and maintainable Perl

Questions?

Page 36: Introduction to writing readable and maintainable Perl

Contact Me

http://kaoru.slackwise.net/

@kaokun on Twitter

My Code

http://search.cpan.org/~kaoru/

https://github.com/kaoru/

Slides

http://www.slideshare.net/kaokun