Date post: | 10-May-2015 |
Category: |
Technology |
Upload: | alex-balhatchet |
View: | 986 times |
Download: | 1 times |
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
Who Am I?
Working at
• 5+ years of code
• 727 modules
• 1107 test files
• Lots of legacy code
• All Perl
Alex Balhatchet
• Super Nerd since 1985
• Perl Hacker since 2002
• Londoner since 2004
• Paid Perl Hacker since 2006
What's this all about?
• Pragmas
• CPAN
• Best Perl Best Practices
• The Real World
• Questions
Pragmas
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
...and use warningsuse 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
Other Useful Pragmasmake open() and others die on error
use autodie;
use new Perl features
use feature ':5.14'; # enable all of themuse feature 'say'; # enable one at a time
make warnings throw exceptions
use warnings FATAL => 'all';
CPAN
The CPANThe CPAN is by far the best thing about Perl.
http://search.cpan.org
98,000 modules! Using CPAN modules means your code gets maintained, bug-fixed and optimized for you!
Picking CPAN ModulesWith 98,000 modules it can be difficult to pick the right one...
Which is the right one for the job?
Picking CPAN ModulesUse the CPAN Testers reports, rt bug tracker, and Reviews. Every Distribution will have these!http://search.cpan.org/dist/Data-Dumper/
Picking CPAN ModulesThe 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!
The BestPerl Best Practices
Perl Best PracticesPerl Best Practices is an amazing book that was published in 2005
PBP contains some great tips forwriting readable and maintainable Perl code... and some silly ideas like inside-out objects ;-)
But seriously, read it. It will make youa better programmer.
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();
Throw ExceptionsThere are many reasons Exceptions win out over error codes.
• Impossible to ignore• Functions don't have to try to return two values• Separate exceptional from non-exceptional cases
Throw ExceptionsPerl 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};
Use builtinsBuiltins 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.
Use builtinswhile (my $line = readline $fh) { # ...}
Is more readable than...
while (my $line = <$fh>) {
# ...
}
Especially for people less familiar with Perl!
Use builtinsmy @log_files = glob "*.log";
Is more readable (and less prone to error) than...
my @log_files = <*.log>;
(Especially when your syntax highlighter thinks that log is the log() function and highlights it yellow :-))
Use builtinsif (defined $value){ # stuff...}
Is less prone to error than...
if ($value){ # stuff...}
Use builtinswarn "Something went wrong!";
Is way better than...
print STDERR "Something went wrong!";
See perldoc f warn for all the awesome details :-)
Use honorary builtinsThere 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);
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!
Avoid overly confusing idioms and cleverness
What does this do?
my $result = [ $result1 => $result2 ] >[ $result2 <= $result1 ];
Avoid overly confusing idioms and cleverness
Maybe it's more obvious like this... use List::Util qw(min); my $result = min($result1, $result2);
The Real World
Why do we want maintainable code?To be able to maintain it of course!
Especially important
• When working on a long-lived project
• When working on a team
• When team members are added frequently
Coding Style Guidelines
• Set out rules for all new development
• Match existing code as closely as is sensible
• Embrace the Best Practices and the Modern
• Give you something concrete to point to when somebody writes something you don't agree with
• Give you something to work from for code reviews
The Golden RulesWe have an Asimovian set of rules at the top of our Coding Style Guide document...
Rule One: Follow the style of the surrounding code
Rule Two: Follow the rules of the Coding Style Guide
Rule Three: Follow Perl Best Practices
Refactoring for StyleBasically follows the same rules as regular refactoring...
• 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!
Perl::Critic
Perl::Critic, and its executable friend perlcritic, is a tool which will tell you what is wrong with your Perl code. % perlcritic my_script.pl
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 style problems can you spot?
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!!
Perl::CriticHow we use Perl::Critic at Nestoria...
● Nightly test run critiques code
● Writes output to a separate log file
● If any failures occur, a single file is chosen to be the one to fix for the day. The current “Engineer of the Week” fixes it
● Within 3 months we had zero Perl::Critic violations!
● New violations are solved almost immediately!
Questions etc.
Questions?
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