Introduction to writing readable and maintainable Perl


Published on

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

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Introduction to writing readable and maintainable Perl

  1. 1. 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
  2. 2. Who Am I?Alex Balhatchet Working for a small company Super Nerd since 1985 ~5 years of code Perl Hacker since 2002 582 modules Londoner since 2004 Lots of legacy code Paid Perl Hacker since All Perl 2006
  3. 3. Who are you guys? Perl Oldies? Perl Newbies? Curious non-Perl types?
  4. 4. Im 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);}
  5. 5. Summary Pragmas CPAN Best Perl Best Practices Legacy Code Perl::Critic & Perl::Tidy Questions
  6. 6. Pragmas
  7. 7. Always use strictuse strict makes your code safer requires that all variables are declared with "my", "our", etc. - stops you from making typos in variable names stops you from using symbolic (string) references - stops you from writing terrible terrible code does not allow non-subroutine barewords - stops you making typos in subroutine calls
  8. 8. ...and use warningsuse warnings ensures that odd things do not silently try to "dowhat 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
  9. 9. 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;
  10. 10. CPAN
  11. 11. The CPANThe CPAN is by far the best thing about Perl.http://search.cpan.org90,000 modules!Using CPAN modules means your code gets maintained, bug-fixed and optimized for you!
  12. 12. Picking CPAN ModulesWith 90,000 modules it can be difficult to pick the right one...Which is the right one for the job?
  13. 13. Picking CPAN ModulesUse the CPAN Testers reports, rt bug tracker, and Reviews.Every Distribution will have these! Testers: PASS (561) FAIL (8) UNKNOWN (4)Rating: (9 Reviews)
  14. 14. Picking CPAN ModulesThe Task::Kensho CPAN module is a documentation-and-dependencies-only distribution which can be used as arecommended modules list.Some highlights are...App::cpanminus, Test::Most, Try::Tiny,Devel::NYTProf, Perl::Critic, DateTime,Config::General, and App::AckIts a great starting point!
  15. 15. Best Perl Best Practices
  16. 16. Code in paragraphsCode 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();
  17. 17. Throw ExceptionsModern programming wisdom gives us many reasonsExceptions win out over error codes. Impossible to ignore Functions dont have to try to return two values Separate exceptional from non-exceptional cases
  18. 18. Throw ExceptionsPerl implements Exceptions with strings and die().die "Exception!";You can use eval() to catch them, but the Try::Tiny modulegives us Java-style try/catch keywords which are much nicer.try { stuff();}catch { # exception is in a lexically scoped $_ variable}
  19. 19. Use builtinsBuiltins in Perl are sensible and readable, especially when youreditor has decent syntax highlighting.Perl is excellent at string manipulation and dealing with lists.Use it to its full potential.Perls builtins have well defined names and behaviours, learn tolove them.
  20. 20. Use builtinswhile (my $line = readline while (my $line = <$fh>) {($fh)) { # ... # ... }}warn "warning! somethings print STDERR "is this a warning? whoweird"; knows?!";
  21. 21. Use builtinsif (defined $value){ if ($value){ # stuff... # stuff...} }my @files = glob("*. my @files = <*.txt>;txt");
  22. 22. Use honorary builtinsThere are a number of "honorary builtins" which are exportedby 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);
  23. 23. Avoid overly confusing idioms and clevernessPerl 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 admittingthat some of the ways to do it suck!
  24. 24. Avoid overly confusing idioms and clevernessWhat does this do?my $result = [ $result1 => $result2 ] ->[ $result2 <= $result1 ];
  25. 25. Avoid overly confusing idioms and clevernessMaybe its more obvious like this... use List::Util qw(min);my $result = min($result1, $result2);
  26. 26. Legacy Code
  27. 27. Be consistent with existing codeThis is an important rule, because it often contradicts all theothers Ive mentioned: When dealing with an existing code base, be consistent.
  28. 28. Perl::Critic & Perl::Tidy
  29. 29. Be consistent with existing codeIf you change the existing code... Make sure there are tests Make sure there are good tests Change the whole file so that consistency is maintained Commit your changes to your VCS as a whole, without any other changes!
  30. 30. Perl::CriticPerl::Critic, and its binary friend perlcritic, is a tool which will tellyou what is wrong with your Perl code.% perlcritic
  31. 31. Perl::Critic#!/usr/bin/perluse feature say;open(IN, $0);while (<IN>) { chomp; foreach (sort keys %letters) { for (split //, $_) { say "$_t$letters{$_}"; $letters{$_}++; } }} close(IN);How many mistakes can you spot?
  32. 32. Perl::Critic% perlcritic --verbose 11 bad_perl.plBareword file handle opened at line 3, near open(IN, $0);. InputOutput::ProhibitBarewordFileHandles (Severity: 5) Using bareword symbols to refer to file handles is particularlyevil because they are global, and you have no idea if that symbolalready points to some other file handle. You can mitigate some of that riskby......Contains the full Perl Best Practices text!!
  33. 33. Perl::TidyPerl::Tidy, and perltidy, is a tool for automatically tidying up Perl codeto make it more readable.It can... convert tabs into spaces restrict lines to 80 characters automatically line up "=>" characters in hashes and ","s in lists add semi-colons where they belong un-cuddle elsesThe perltidyrc file listed in Perl Best Practices can be found here:
  34. 34. Questions etc.
  35. 35. Questions?
  36. 36. Contact Me @kaokun on Twitter My Code Slides