Perl Programming Page 2 - Debugging Perl |
No matter how many different debugger applications or integrated development environments I use, I still find that plain ol’ print is my best debugger. I could load source into a debugger, set some inputs and breakpoints, and watch what happens, but often I can insert a couple of print statements and simply run the program normally.† I put braces around the variable so I can see any leading or trailing whitespace: print "The value of var before is [$var]\n"; #... operations affecting $var; print "The value of var after is [$var]\n"; I don’t really have to use print because I can do the same thing with warn, which sends its output to standard error: warn "The value of var before is [$var]"; #... operations affecting $var; warn "The value of var after is [$var]"; Since I’ve left off the newline at the end of my warn message, it gives me the filename and line number of the warn: The value of var before is [$var] at program.pl line 123. If I have a complex data structure, I use Data::Dumper to show it. It handles hash and array references just fine, so I use a different character, the angle brackets in this case, to offset the output that comes from Data::Dumper: use Data::Dumper qw(Dumper); Those warn statements showed the line number of the warn statement. That’s not very useful; I already know where the warn is since I put it there! I really want to know where I called that bit of code when it became a problem. Consider a divide subroutine that returns the quotient of two numbers. For some reason, something in the code calls it in such a way that it tries to divide by zero:‡ sub divide return $numerator / $denominator; I know exactly where in the code it blows up because Perl tells me: Illegal division by zero at program.pl line 123. I might put some debugging code in my subroutine. With warn, I can inspect the arguments: sub divide return $numerator / $denominator; I might divide in many, many places in the code, so what I really need to know is which call is the problem. That warn doesn’t do anything more useful than show me the arguments. Although I’ve called print the best debugger in the world, I actually use a disguised form in the carp function from the Carp module, part of the standard Perl distribution. It’s like warn, but it reports the filename and line number from the bit of code that called the subroutine: #!/usr/bin/perl printf "%.2f\n", divide( 3, 4 ); sub divide return $numerator / $denominator; The output changes to something much more useful. Not only do I get my error message, but carp adds some information about the line of code that called it, and it shows me the argument list for the subroutine. I see that the call from line 4 is fine, but the call on line 5 is the last one before Perl kills the program: $ perl show-args.pl The carp function is the better-informed version of warn. If I want to do the same thing with die, I use the croak function. It gives the same message as carp, but just like die, croak stops the program.
blog comments powered by Disqus |
|
|
|
|
|
|
|