Unravelling the Spaghetti: Perl Best Practices and Existing Code

12 Steps toward Programmer Recovery

Peter Karman

http://www.peknet.com/~karpet/slides/fp/spaghetti

Step 1: Brokenness

We admitted we were powerless over entropy and that our code had become unmanageable.

Real life #129

 % ls -l
 -rwxr-xr-x 1 pek     2008-01-22  logout.cgi.new
 -rwxr-xr-x 1 joe     2007-03-02  logout.cgi.broken
 -rwxr-xr-x 1 sam     2006-09-12  logout.cgi.old
 -rwxr-xr-x 1 ann     2005-03-26  logout.cgi.032605
 -rwxr-xr-x 1 lil     2004-06-10  logout.cgi~
 -rwxr-xr-x 1 fred    1999-01-08  logout.cgi

Step 2: Seeking

Came to believe that a Power greater than ourselves could restore us to sanity.

Sanity is hard work.

A toolkit:

Step 3: Repentance

Made a decision to turn our style over to the care of DCONWAY as we understood him.

"...as we understood him"


   unless ( $you->have( $good_reason ) ) {
       $you->follow( 'conventions' );
   }

  • talk amongst yourselves
  • reduce $grok_time
  • diff -u
  • easier to refactor

Brevity != godliness

Don't:

   $you->follow( 'conventions' ) 
      unless $you->have( $good_reason );

Do:

   unless ( $you->have( $good_reason ) ) {
       $you->follow( 'conventions' );
       $you->grumble;
       $you->get_paid and $you->get_over_it;
   }

Larry Wall said:

...stylistic limits should be self-imposed, or at most policed by consensus among your buddies.
But Damian Conway warns against Intuitive Programmer Syndrome

Step 4: Scrutiny

Made a searching and fearless moral inventory of our code.

Put it in Subversion now, clean up later

 % svn mkdir http://http://svn.my.org/code -m init
 % cd my/file/tree
 % svn co http://http://svn.my.org/code .
 % svn add *
 % svn commit -m 'import'
 # peek at every thing in /code and toss chunks
 % svn rm http://svn.my.org/code/crufty -m 'bye'

Step 5: Confession

Admitted to $Boss, to ourselves and to another human being the exact nature of our wrongs.

If I could do it over again...

Poorly-written Perl reflects poorly on the community.
  •   # serenity prayer
      use strict;
      use warnings;         
    
  • optimize for developer time
  • avoid magic -- make it plain

...and again...

  • one package == one .pm file. "Have another file. They're free."
  • globals == bad
  • use local for punctuation vars like $/
  • chained join/map/grep/sort/grep/map/split ...

Step 6: Agony

Were entirely ready to have Perl::Critic identify all these defects of character.

Be Brave

  use Perl::Critic;
  my $file = shift;
  my $critic = Perl::Critic->new();
  my @violations = $critic->critique($file);
  print @violations;  

Step 7: Baptism

Humbly asked Perl::Tidy to remove our shortcomings.

Vim!

 % cat ~/.vimrc
 map t :%!perltidy

Nedit!!

    nedit.shellCommands: \
        perltidy-pbp:F5::ESL:\n\
                perltidy -pbp % > %.tdy && mv %.tdy %\n

Step 8: Recompense

Made a list of all persons we had harmed, and became willing to make amends to them all.

Real life #409

 my @amends_needed = qw(
    guy_who_inherited_my_code_at_old_job
 );
 
 foreach my $person (@amends_needed) {
    buy_beer( $person );
 }

Step 9: Testing

Made direct amends to such people wherever possible, except when to do so would injure them or others.

"...would injure them or others"

Test! Test!! Test!!!

Let go and let POD

  • Keep your POD close at hand.
  • Be kind to your self.
  • Build it in to the project timeline.
  • Module::Starter

Step 10: Perseverance

Continued to take personal inventory and when we were wrong promptly admitted it.

Carp + Data::Dump

Catastrophic failure is a good thing.

Step 11: Practice

Sought through prayer and meditation to improve our conscious contact with PBP, as we understood them, praying only for knowledge of their will for us and the power to carry that out.

TMTOWTDI: the anti-hubris

  while ( $you->get( 'older' ) ) {
      $you->lose( $need_to_be_right );
  }

Step 12: Evangelism

Having had a spiritual awakening as the result of these steps, we tried to carry this message to Perl Mongers everywhere and to practice these principles in all our affairs.

Credits

  • http://www.12step.org/
  • Perrin Harkins for his 2006 OSCON talk on "Low-Maintenance Perl"
  • Matt Trout for "warn() is my favorite debugger"
  • Marvin Humphrey for "catastrophic failure is a good thing."
  • Lee Carmichael for beers and good conversation on what not to do.
  • Bridget Kromhout for reviewing these slides

One Line at a Time


xkcd ftw