Last updated: 28 November 2006
Met Office
FitzRoy Road, Exeter
Devon, EX1 3PB
United Kingdom
© Crown copyright 2005-6. All rights reserved.
Questions regarding this document or permissions to quote from it should be directed to the IPR Manager.
Perl (Practical Extraction and Report Language) is gaining a lot of popularity at the Met Office for developing applications that are traditionally programmed using shell script. For example, it is currently our choice of language for developing the in-house components of the FCM system.
Perl is a very powerful general purpose scripting tool that is free and portable across a huge variety of platforms including many non-Unix systems. Replacing a shell script with an equivalent Perl program often results in a massive reduction in runtime - using cleaner syntax and algorithm.
Perl is a language with a rich set of "grammar". To most people, the first impression of a piece of code written in Perl is that it is very ugly. Its lines are full of punctuation junks that nobody can hope to understand. This is often caused by poorly written programs coupled with little and often inadequte documentations. To improve readability and to reduce the overheads of maintenance, it is important for Perl programmers to write their code in a nice and consistent way.
The aim of this document is to propose ideas on how the Perl programming language should be used with FCM.
There are many Perl style guides available online. Some are listed below:
perlstyle
and perlmodstyle
It is worth noting that the ideas in some of the Perl style guides may conflict with each other - as they are targeted to different people. However, there is a common theme to most of the best practices. The following is a summary:
The main question is: what should we include in our coding standard? Although we would like to recommend using the best practices described in the last section, we would not want to impose any restriction, as Perl is a language designed to do things in many different ways. The only thing we would like to impose is a header block in each source file, and a header comment block for each function in a source file.
For a Perl executable, the header block of the source file should contain the following:
Executable header block example |
---|
#!/usr/bin/perl # ------------------------------------------------------------------------------ # NAME # example.pl # # SYNOPSIS # example.pl [options] args # # DESCRIPTION # This is a header example, and so on and so forth. # # OPTIONS # -b [--bar] - this option does what "bar" does. # -f [--foo] - this option does what "foo" does. # # ARGUMENTS # args - description of each argument. # # SEE ALSO # list of relevant commands, modules and documents # # COPYRIGHT # (C) Crown copyright Met Office. All rights reserved. # For further details please refer to the file COPYRIGHT.txt # which you should have received as part of this distribution. # ------------------------------------------------------------------------------ # Standard pragmas use strict; use warnings; # Standard modules use Getopt::Long; # ------------------------------------------------------------------------------ # Process options my ($foo, $bar); GetOptions ( 'foo|f' => \$foo, 'bar|b' => \$bar, ); # Process arguments my $arg = shift @ARGV; # Do something... print 'This is an example: ', $arg, "\n"; print 'FOO', "\n" if $foo; print 'BAR', "\n" if $bar; __END__ |
For a Perl module, the header block of the source file should contain the following:
Module header block example |
---|
#!/usr/bin/perl # ------------------------------------------------------------------------------ # NAME # Metoffice::Example # # DESCRIPTION # This is a header example, and so on and so forth. # # SEE ALSO # list of relevant commands, modules and documents # # COPYRIGHT # (C) Crown copyright Met Office. All rights reserved. # For further details please refer to the file COPYRIGHT.txt # which you should have received as part of this distribution. # ------------------------------------------------------------------------------ package Metoffice::Example; # Standard pragmas use strict; use warnings; # Exports our (@ISA, @EXPORT, @EXPORT_OK); require Exporter; @ISA = qw(Exporter); @EXPORT = qw( foo bar ); # ------------------------------------------------------------------------------ # ... some more Perl ... # ------------------------------------------------------------------------------ 1; __END__ |
The header of a function (or "method" for OO code) should have the following:
Function header block example |
---|
# ... Something before the function ... # # ------------------------------------------------------------------------------ # SYNOPSIS # $result = &print_hello; # $result = &print_hello ($arg); # # DESCRIPTION # Print the word "hello" to standard output. If no argument is specified, # the word "world" will be printed after the word "hello". Otherwise, the # word specified by the argument $arg will follow "hello". The function # returns true on success. # # ARGUMENTS # $arg - optional, describe $arg if it has not been done in the above section # ------------------------------------------------------------------------------ sub print_hello { my ($arg) = @_; $arg = defined ($arg) ? $arg : 'world'; my $result = print 'hello ', $arg, "\n"; return $result; } # ------------------------------------------------------------------------------ # # ... Something after the function ... |