Unless otherwise noted, articles © 2005-2008 Doug Spencer, SecurityBulletins.com. Linking to articles is welcomed. Articles on this site are general information and are NOT GUARANTEED to work for your specific needs. I offer paid professional consulting services and will be happy to develop custom solutions for your specific needs. View the consulting page for more information.


Perl Guidelines

From SecurityBulletins.com

Jump to: navigation, search

Written by Doug Spencer - Feb 3, 2008

Perl Programming Guidelines

I often hear about how Perl code is difficult to maintain and understand. I find that most of the problem originates from programmers who take a shotgun approach to writing code, rather than using methodology. The language allows a great deal of flexibility. The flexibility makes it easy to write small, quick and dirty scripts to get a task done. When writing code that will be used more than once, it is important to write your code to a higher standard.

I have put together the following article to discuss a few of the items I have found work well to write maintainable Perl code.

First, in a production program, you want to be able to find errors before they cause catastrophic failures. You can find errors by enabling strict, taint checking, and warnings. They are enabled by using the following in your code:

 #!/usr/bin/perl -wT
 use strict;

The -w enables warnings which causes the compiler to spit out complaints about more possible issues, such as using uninitialized variables. The -T enables taint checking. Taint checking looks for user supplied information that is used in insecure ways, such as unfiltered user supplied input used to specify a filename to open. Use strict checks that subs, vars, and refs are used in a safe way. For instances, strict will require variables be defined with "my" to specify they are local to the section of code. Be sure to actually fix any issues that arise, rather than simply disabling the check. The checks are alerting to potential problems, and ignoring problems doesn't make them go away.

Second, you should actually use local variables. Keep your variables as localized as possible. This allows debugging to be compartmentalized to the specific routine or loop that is being debugged. If you need outside data in a subroutine, pass it in, rather than defining a variable with a global scope. This helps to avoid overall naming conflicts.

Third, use subroutines intelligently. I mean pass data that should be passed in, and have return values that make sense and have some useful function. A good trick to use when passing data to subroutines is to pass a hash => key pair and retrieve values as a hash in the subroutine. In this way, you can do something like:

 #!/usr/bin/perl -wT 
 use strict;

 my $return = &testsub(greeting=>"Hello", quit=>"GoodBye");
 exit $return;

 sub testsub {
   my %message = @_;

   print $message{greeting} . "\n";
   print $message{quit} . "\n";
   return 0; # successful return code

 } # testsub

Fourth, use the symbol designators to show how you are using a value. If you're using a scalar, then use $, for arrays, use @, for hash values, use %, and for subroutines, use the ampersand &. These will allow future reviewers to see how the value is intended to be used.

Fifth, I often define variables that are used "globally" as "my" variables at the top of the program, then move the main functionality of the program to a subroutine called "main" and localize variable used in the main loop in that routine. I then call &main; just above the routine.

Sixth, comment your brace ends. As shown above where I have # testsub at the end of the subroutine. I also do this for loops and conditionals. It allows you to quickly see if a brace is missing and also to see what items are nested inside other items.

Seventh, use proper indenting of your code. An easy way to do this is with a code beautifier. Using the beautifier allows you to quickly find constructs that weren't properly opened or closed.

Eighth, use modules when available. Modules are often well tested pieces of reusable code. There is little reason to re-write the functionality of a module. If you find a bug in a module, submit the issue to the module author so it can be incorporated into future releases.

Ninth, put the start of the code at the top of the program. Someone looking at your code is probably going to look at the code starting from the top. I usually put any user defined values at the very top of my programs and comment that they are user configurable.

Tenth, if your program uses command line arguments, put a help output in place to show what options are available and how they are used.

Eleventh, comment where it makes sense. Comments should be descriptive and don't have to be obtrusive.

Personal tools