To give a concrete example, here is the
source code for the slides of a talk on
Perl Best Practices
I gave to Sydney.pm last week.
----
presentation_topic: Perl Best Practices
presentation_title: Perl Best Practices
presentation_place: James Squire Pub, Sydney
presentation_date: September 21, 2005
----
= Perl Best Practices
Why read it?
* It will make you a better *programmer*
* It will make you a better *Perl* programmer
* You and your team will write better code
* More Robust
* More Efficient
* More Maintainable
----
There are 256 guidelines. Coincidence?
Here is the most important one:
= Always code as if the guy who ends up maintaining your code will be
+a violent psychopath who knows where you live
And that violent psychopath is most likely you, six months from now.
----
= But why is Damian qualified to write this book?
----
= use Acme::Bleach;
package Acme::Bleach;
$VERSION = '1.12';
my $tie = " \t"x8;
sub whiten { local $_ = unpack "b*", pop; tr/01/ \t/; s/(.{9})/$1\n/g
+; $tie.$_ }
sub brighten { local $_ = pop; s/^$tie|[^ \t]//g; tr/ \t/01/; pack "b
+*", $_ }
sub dirty { $_[0] =~ /\S/ }
sub dress { $_[0] =~ /^$tie/ }
open 0 or print "Can't rebleach '$0'\n" and exit;
(my $shirt = join "", <0>) =~ s/.*^\s*use\s+Acme::Bleach\s*;\n//sm;
local $SIG{__WARN__} = \&dirty;
do {eval brighten $shirt; exit} unless dirty $shirt && not dress $shi
+rt;
open 0, ">$0" or print "Cannot bleach '$0'\n" and exit;
print {0} "use Acme::Bleach;\n", whiten $shirt and exit;
----
= The Horror that is SelfGOL
... can print its own source code (self-replicate), rewrite other Perl
+ programs so
they can print their own source code (and still perform their original
+ functions),
detect un-rewritable Perl programs, play John Conway's Game of Life us
+ing its own
source code or a specified file as a pattern for the board with a boar
+d of arbitrary
size, or animate a rotating banner of an arbitrary short amount of tex
+t.
All this in under 1000 bytes of Perl without using a single if, unless
+, while, until,
for, foreach, goto, next, last, redo, map, or grep.
Everything you never wanted to know about Perl, and would have been af
+raid to ask.
#!/usr/bin/perl -s
$;=$/;seek+DATA,!++$/,!$s;$_=<DATA>;$s&&print||$g&&do{$y=($x||=20)*($
+y||8);sub
i{sleep&f}sub'p{print$;x$=,join$;,$b=~/.{$x}/g}$j=$j;sub'f{pop}sub
n{substr($b,&f%$y,3)=~tr,O,O,}sub'g{$f=&f-1;($w,$w,substr($b,&f,1),O)
+[n($f-$x)+
n($x+$f)-(substr($b,&f,1)eq+O)+n$f]||$w}$w="\40";$b=join'',@ARGV?<>:$
+_,$w
x$y;$b=~s).)$&=~/\w/?O:$w)ge;substr($b,$y)=q++;$g='$i=0;$i?$b:$c=$b;
substr+$c,$i,1,g$i;$g=~s?\d+?($&+1)%$y?e;$i-$y+1?eval$g:do{$i=-1;$b=$
+c;p;i
1}';sub'e{eval$g;&e}e}||eval||die+No.$;
__DATA__
if($j){{$^W=$|;*_=sub{$=+s=#([A-z])(.*)#=#$+$1#=g}}
@s=(q[$_=sprintf+pop@s,@s],q[
if($j){{$^W=$|;*_=sub{$=+s=#([A-z])(.*)#=#$+$1#=g}} #_The_Perl_Jo
+urnal_#
@s=(q[%s],q[%s])x2;%s;print"\n"x&_,$_;i$j;eval}
])x2;$_=sprintf+pop@s,@s;print"\n"x&_,$_;i$j;eval}$/=$y;$"=",";print
q<#!/usr/local/bin/perl -sw
if(!$s){>.($_=<>).q<}else{@s=(q[printf+pop@s,@s],q[#!/usr/local/bin/p
+erl -sw
if(!$s){>.(s$%$%%$g,tr=[=[===tr=]=]=||&d,$_).q<}else{@s=(q[%s],q[%s])
+x2;%s}
])x2;printf+pop@s,@s}
----
= use Lingua::Romana::Perligata;
use Lingua::Romana::Perligata;
adnota Illud Cribrum Eratothenis
maximum tum val inquementum tum biguttam tum stadium egresso scribe.
vestibulo perlegementum da meo maximo .
maximum tum novumversum egresso scribe.
da II tum maximum conscribementa meis listis.
dum damentum nexto listis decapitamentum fac sic
lista sic hoc tum nextum recidementum cis vannementa da listis
+.
next tum biguttam tum stadium tum nextum tum novumversum
scribe egresso.
cis
----
= OK, OK, Some Serious Production Code
From the Perl6::Rules Changes file:
0.02 Mon Apr 12 13:23:18 2004
- Updated requirement to 5.8.3
- Removed stupid 'use strict' ;-)
----
= Here's the real reason why
----
{image: images/damian.jpg}
----
* Author of over 50 CPAN modules
* Lead designer of Perl 6
* Computer Science Professor
* Author of classic book "Object Oriented Perl"
* Brilliant Speaker and Writer
* Damian has the *authority* to settle arguments
----
= History
About 60% of the book material was originally given as a
two day course (see PJF advertisement ;-).
People who did the course asked: "Why not make it into a book?".
Others argued that such an *authorative* book would make it much
easier for them to enforce Perl coding standards on their team.
BTW, his next book will probably be the subject of PJF's presentation:
"How to give great presentations".
----
= Top 10 Development Practices
* Design the Module's Interface First
* Write the Test Cases Before the Code
* Create Standard POD Templates for Modules and Applications
* Use a Revision Control System (not SourceSafe ;-)
* Create Consistent Command-Line Interfaces
* Agree Upon a Coherent Layout Style and Automate It with /perltidy/
* Code in Commented Paragraphs
* Throw Exceptions Instead of Returning Special Values or Setting Flag
+s
* Add New Test Cases Before you Start Debugging
* Don't Optimize Code -- Benchmark It
----
= Top 10 Coding Practices
See the book.
----
= Top 10 Module Practices
See the book.
----
= Examples
----
= Passing arguments to subroutines
Use named arguments for any subroutine that is ever likely to have mor
+e than three parameters.
Named arguments replace the need to remember an ordering (which humans
+ are poor at)
with the need to remember a name (which humans are good at).
Don't use:
padded( text => $line, centred => 1 )
use:
padded({ text => $line, centred => 1 })
Why?
----
= Use block if, not postfix if
$sum += $measurement if defined $measurement
is ok, but does not scale when you need to change the code. Compare:
$sum += $measurement
and $count++
and next SAMPLE
if defined $measurement;
to:
if (defined $measurement) {
$sum += $measurement;
$count++;
next SAMPLE;
}
The second form *scales* better, a common theme throughout the book.
----
= Smart::Comments
Damian recommends many modules in the book (detailed in the Appendix).
Here's one that I like:
use Smart::Comments;
my $results = $scenario->project_outcomes();
### $results
Comment-based assertions are also supported:
### check: @candidates >= @elected
To switch off in production, simply:
# use Smart::Comments;
----
= What's wrong with this code?
my $source_file = 'fred.tmp';
my $destination_file = $source_file;
# Open both filehandles...
use Fatal qw( open );
open my $src, '<', $source_file;
unlink $destination_file;
open my $dest, '>', $destination_file;
# Read, process, and output data, line-by-line...
while (my $line = <$src>) {
print {$dest} transform($line);
}
sub transform {
return "hello:" . $_[0];
}
----
= Don't be clever
[ $a => $b ] -> [ $b <= $a ]
----
= Don't be clever
$a <= $b ? $a : $b
use List::Util qw(min);
min($a, $b)
----
= Object Oriented Perl
Traditional Perl O-O has some problems:
* Poor encapsulation
* Misspelled attributes are trouble at runtime
Inside-out objects:
* One lexical hash per attribute indexed by object
* See Class::Std and Class::Std::Utils
* Excellent encapsulation
* Misspelled attributes now caught at compile time
* DESTROY is now very important
----
* http://www.perl.com/pub/a/2005/07/14/bestpractices.html
* http://www.perlcast.com/audio/Perlcast_Interview_003_Damian_Conway.m
+p3
* http://perlcast.com/audio/Perlcast_Presentation_001_Conway_Channel_O
+SCON_2005.mp3
* http://www.linuxjournal.com/article/8567
* http://perltraining.com.au/courses/bestpractice.html
* http://www.perlmonks.org/index.pl?node_id=477093 (Book Review)
* http://www.perlmonks.org/?node_id=488824 (Best Practice or Dodgy Pra
+ctice?)
* http://books.slashdot.org/books/05/09/14/1451238.shtml?tid=145&tid=6
+ (Usual cheer-leading. Who is Tony Williams?)
----
= CPAN Modules
* See recommended module list in PBP
* Module::Starter::PBP
* ExtUtils::ModuleMaker::PBP
* Perl::Critic
* Perl::BestPractice
----
Buy the book and thankyou for listening!