This excerpt is from Mastering Perl.
This is the third in O'Reilly's series of landmark Perl tutorials, which started with Learning Perl, the bestselling introduction that taught you the basics of Perl syntax, and Intermediate Perl, which taught you how to create re-usable Perl software. Mastering Perl pulls everything together to show you how to bend Perl to your will.
After several years of teaching Perl and helping other people solve their Perl problems, I wrote a guide that showed how I think through a problem. It’s appeared on a couple of web sites and there are even a couple of translations.Some of the stuff I did unconsciously, and those are the hardest things to pass on to a new programmer. Now that I have this guide, other people can develop their own problem-solving skills. It might not solve all of your Perl problems, but it’s a good way to try.
Forget about code ownership. You may think yourself an artist, but even the Old Masters produced a lot of crap. Everybody’s code is crap, which means my code is crap and your code is crap. Learn to love that. When you have a problem, your first thought should be “Something is wrong with my crappy code.” That means you do not get to blame Perl. It is not personal.
Forget about how you do things. If the way you did things worked, you would not be reading this. That is not a bad thing. It is just time to evolve. We’ve all been there.
If you have a problem with your program it is just that—your problem. You should do as much to solve it by yourself as you can. Remember, everyone else has their own programs, which means they have their own problems. Do your homework and give it your best shot before you bother someone else with your problems. If you honestly try everything in this guide and still cannot solve the problem, you have given it your best shot and it is time to bother someone else.
Fix things so you do not have the same problem again. The problem is probably how you code, not what you code. Change the way you do things to make your life easier. Do not make Perl adapt to you, because it won’t. Adapt to Perl. It is just a language, not a way of life.
If you aren’t already using strictures, turn it on. Perl gurus
are gurus because they use
strict, which leaves
them more time to solve other problems, learn new things, and upload
working modules to CPAN.
You can turn on strictures within the code with the
perl -Mstrict program.pl
You may be annoyed at strictures, but after a couple of weeks of programming with them turned on, you’ll write better code, spend less time chasing simple errors, and probably won’t need this guide.
Perl can warn you about a lot of questionable constructs. Turn on warnings and help Perl help you.
You can turn on warnings from the command line:
$ perl -w program.pl
Lexical warnings have all sorts of interesting features. See
warnings pragma documentation for the
If you don’t understand a warning, you can look up a verbose version of the warning in perldiag or you can use the diagnostics pragma in your code:
After you get error or warning messages from
perl, fix the first message then see if
perl still issues the other messages. Those extra
messages may be artifacts of the first problem.
Perl gives you warning messages when it gets worried and not
before. By the time
perl gets worried, the
problem has already occurred and the line number
perl is on may actually be
after the problem. Look at the couple of
expressions before the line number in the warning.
Don’t guess! Verify everything! Actually examine the value right before you want to use it in an expression. The best debugger in the universe is print:
print STDERR "The value is [$value]\n";
$value in brackets so I can see
any leading or trailing whitespace or newlines. If I have anything
other than a scalar, I use
Data::Dumper to print
the data structures:
require Data::Dumper; print STDERR "The hash is ", Data::Dumper::Dumper( %hash ), "\n";
If the value is not what you think it is, back up a few steps and try again! Do this until you find the point at which the value stops being what you think it should be!
You can also use the built-in Perl debugger with
-d switch. See
perldebug for details:
perl -d program.pl
You can also use other debuggers or development environments, such as ptkdb (a graphical debugger based on Tk) or Komodo (ActiveState’s Perl IDE based on Mozilla). I cover debugging in Chapter 4, Debugging Perl.
I have been programming Perl for quite a long time and I still
look at perlfunc almost every day. Some things
I just cannot keep straight, and sometimes I am so sleep-deprived
that I take leave of all of my senses and wonder why
sprintf() does not print to the screen.
You can look up a particular function with the
perldoc command and its
perldoc -f function_name
If you’re using a module, check the documentation to make sure
you are using it in the right way. You can check the documentation
for the module using
Again, I constantly refer to perlvar. Well, not really since I find The Perl Pocket Reference much easier to use.
Some modules change behavior between versions. Do you have the
version of the module that you think you have? You can check the
installed module version with a simple
perl -MModule::Name -le 'print Module::Name->VERSION';
If you’re trying something new or think a particular piece of code is acting funny, write the shortest possible program to do just that piece. This removes most of the other factors from consideration. If the small test program does what it thinks it does, the problem probably isn’t in that code. If the program doesn’t do what you think it should, then perhaps you have found your problem.
Some things depend on environment variables. Are you sure that they are set to the right thing? Is your environment the same that the program will see when it runs? Remember that programs intended for CGI programs or cron jobs may see different environments than those in your interactive shell, especially on different machines.
Perl stores the environment in
%ENV. If you
need one of those variables, be ready to supply a default value if
it does not exist, even if only for testing.
If you still have trouble, inspect the environment:
require Data::Dumper; print STDERR Data::Dumper::Dumper( \%ENV );
If you have a problem, somebody else has probably already had that problem. See if one of those other people posted something to the Usenet group comp.lang.perl.misc by searching Google Groups (http://groups.google.com). The difference between people who ask questions on Usenet and those who answer them is the ability to use Google Groups effectively.
If you want to track down the slow parts of the program, have
you profiled it? Let
Devel::SmallProf do the
heavy lifting for you. It counts the times
executes a line of code as well as how long it takes and prints a
nice report. I cover profiling in Chapter 5, Profiling Perl.
If you have a test suite, which test fails? You should be able to track down the error very quickly since each test will only exercise a little bit of code.
If you don’t have a test suite, why not make one? If you have
a really small program or this is a one-off program, then I’m not
going to make you write a couple of tests. Anything other than that
could really benefit from some test programs. The
Test::More module makes this extremely simple,
and if you program your script as a modulino as in Chapter 18, Modules As Programs, you have all the tools of module development
available for your program.
Explain your problem aloud. Actually say the words.
For a couple of years I had the pleasure of working with a really good programmer who could solve almost anything. When I got really stuck I would walk over to his desk and start to explain my problem. Usually I wouldn’t make it past the third sentence without saying, “Nevermind—I got it.” He almost never missed either.
Since you’ll probably need to do this so much, I recommend some sort of plush toy to act as your Perl therapist so you don’t annoy your colleagues. I have a small bear that sits on my desk and I explain problems to him. My girlfriend does not even pay attention when I talk to myself anymore.
You have been staring at the computer screen, so maybe a different medium will let you look at things in a new way. Try looking at a printout of your program.
Seriously. Perhaps you do not like Jon Stewart, so choose something else. Take a break. Stop thinking about the problem for a bit and let your mind relax. Come back to the problem later and the fix may become immediately apparent.
If you’ve have made it this far, the problem may be psychological. You might be emotionally attached to a certain part of the code, so you do not change it. You might also think that everyone else is wrong but you. When you do that, you don’t seriously consider the most likely source of bugs—yourself. Do not ignore anything. Verify everything.
If you enjoyed this excerpt, buy a copy of Mastering Perl
Copyright © 2009 O'Reilly Media, Inc.