Perl - Convenient and Well Written
Often, particularly in its early days before the various movements for better perl, perl code was written badly. Here is an example, do-nothing script/module that serves me as an example of how to write small scripts and modules using some of the better approaches.
With the exception of some POD requirements and minor perltidy(1)ing that I usually don't care about, this code passes Perl::Critic using PBP policies all the way, that is down to Severity: 1 (aka brutal).
It shows perl code as both executable script and module, good pragmas, exception handling, error handling, option processing, argument processing, passing variables by reference and pod.
Clearly, this is not perfect, both in that it is non-comprehensive even for my own purposes and because there are controversies about what actually is the best approach. But I'm not expecting perfection. I wrote it to refer to when I come back to perl after having spent a lot of time programming in other languages.
#!/usr/bin/env perl # $Id$ # $Author$ # $Date$ package Foo; use strict; use warnings; use version; our $VERSION = qv('0.0.1'); use Readonly; use Carp; use Try::Tiny; my %options; Readonly my $USAGE => <<'ENDUSAGE'; Do something Usage: perl foo.pm --bar optionally takes a string value --baz non-zero length (comma-delimited) list of strings --force overwrite destination directory -h, --help print this usage -v, --verbose report activity --debug lots of detail, implies verbose ENDUSAGE if (!(caller()) { __PACKAGE__->run(\@ARGV); } sub run { #takes an arrayref which deferences to @ARGV my $arg_arrayref = $_; require Getopt::Long; GetOptions(\%options, "bar:s", "baz=s@", "force", "debug", "help|h", "verbose|v+", ); if ($help) { croak $USAGE; } twiddle(\%options,$arg_arrayref); return; } sub twiddle { # takes a hashref of options and an arrayref of arguments # unpack the options my($opt_hashref,$arg_arrayref) = @_; my $verbose = ${$opt_hashref{'verbose'}}; my $debug = ${$opt_hashref{'debug'}}; # params::validate? (or carp/croak) for my $arg (@{$arg_arrayref}) { try { do_it($arg); } catch { carp "failed to twiddle $arg: $_"; }; } return; } 1; __END__ =pod =head1 NAME foo - Attempting to demonstrate exemplary code in the sense of being an example of various good practices and techniques =head1 SYNOPSIS =head1 DESCRIPTION Showing perl code as both executable script and module, good pragmas, exception handling, error handling, option processing, argument processing, passing variables by reference, pod. =head1 USAGE use Foo; Foo::twiddle( (baz => ['foo','bar'], verbose => 1 ), ['arg1','arg2']); =head1 REQUIRED ARGUMENTS None =head1 OPTIONS =head1 BUGS AND LIMITATIONS =head1 DEPENDENCIES =head1 TODO Possible improvements =over =item Demonstrate testing =item Demonstrate logging =item Use Params::Validate =item Use pod2usage (look in the docs for pod2usage and L<http://www.vromans.org/johan/articles/getopt.html>) =item More explanation of what's happening, why it's good practice (and what it avoids and why). =back =head1 AUTHOR Duncan Hutty - L<http://www.allgoodbits.org> =head1 LICENSE AND COPYRIGHT This software is Copyright (c) 2012 by Duncan Hutty. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) =cut