Met Office logo

Perl coding standard for FCM

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.

Contents

1. Introduction

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.

2. Online Perl style guides

There are many Perl style guides available online. Some are listed below:

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:

3. Coding standard

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