debug - Perl pragma for debugging and logging of debug lines.
package Foo; # start by embedding calls to # debug::log inside your module # of package. # use the pragma use debug; sub bar { # call debug::log if you have # something to say, but don't # forget "if DEBUG" debug::log("entering Foo::bar") if DEBUG; print "foo"; # you can also call it with the # object '->' syntax if you like. debug->log("leaving Foo::bar") if DEBUG; } 1; # then in your main script, you # can do one of the following things # use your module use Foo; # turn debug on for the Foo package (at compile-time) use debug qw(Foo); # you can also do it this way (at run-time) debug->on("Foo"); # now comes your code ... Foo::bar(); # your would then look like this: debug-log + entering Foo::bar foo debug-log + leaving Foo::bar
The debug pragma provides a very simple way of turning on and off your debugging lines, as well as a very flexible way of logging those lines to literally anywhere you want.
You need to register a module for debugging by placing use debug at the top of you module. Then you can embed calls to debug::log within your code making sure to surround them with conditional checks for the value of the DEBUG constant. See the SYNOPSIS section for an example. After that you can turn the debugging on and off from any other module or namespace. You can do this one of 2 ways:
use debug
debug::log
DEBUG
# compile-time way use debug qw(Foo Bar Baz); # add as many modules as you like # run-time way debug->on qw(Foo Bar Baz); # add as many modules as you like
Now comes the debug log filters. If you do nothing else, your debug lines will look like the example in the SYNOPSIS section. But you can change that very easily. By changing the default log filter with (what else) the set_default_log_filter function. Here is an example:
set_default_log_filter
debug::set_default_log_filter(sub { print STDERR "debugging : ", @_ });
This will send all the debug::log calls to STDERR and prepend the string "debugging : " to them all. Any anyonomous subroutine or subroutine reference will do.
But the default filter is not the only one you can change, you can also assign a specific filter for each package you are debugging. Here is an example:
debug::set_log_filter(Foo => sub { print "Debugging Foo >> ", @_ });
This log filter will only be called from the Foo package. And just as you can add them, you can take them away. Use the remove_log_filter function. Again, an example:
Foo
remove_log_filter
debug::remove_log_filter("Foo");
All debug::log calls in Foo will now go through the default log filter again.
A debug log filter which prints the name of package it was called in.
sub my_calling_package_filter { print "debugging -> ", (caller(1))[0], " : ", @_, "\n"; } debug->set_log_filter(Foo => \&my_calling_package_filter);
A debug log filter to convert things to HTML.
sub my_HTML_log_filter { # first we need to join the arguements into a single string my $output = join "" => @_; # then we replace any \n (newlines) with an HTML <BR> tag $output =~ s/\n/\<BR\>/g; # then we replace any tabs with 4 " "s $output =~ s/\t/\ \;\ \;\ \;\ \;/g; # then we wrap the output in <P> tags and return it return "<P>$output</P>"; } debug->set_log_filter(Foo => \&my_HTML_log_filter);
A debug log filter which will print a basic date stamp.
debug->set_log_filter(Foo => sub { "[" . localtime() . "]: ", @_ } );
Here is a filter which appends to a file.
sub append_to_file { open LOG, ">>", "/tmp/debug.log"; print LOG "debug->log : ", @_; close LOG; } debug->set_log_filter(Foo => \&append_to_file);
This will turn debugging on for all the packages given in the @packages arguement.
@packages
This will turn debugging off for all the packages given in the @packages arguement.
This will return true (1) if debugging is on for that module and false (0) otherwise.
An array of strings and variables (@statements) which will be logged. These values are fead through either the current default log filter or the one assigned specifically to the current package.
@statements
The $log_filter argument is expected to be a subroutine reference, and if it is not, an exception is thrown. For information about how to create the log filters see the above sections.
$log_filter
This assigns a specific $log_filter to a particular $package, from then on all debug-log()> calls from within that package will go through this filter. The $log_filter argument is expected to be a subroutine reference, and if it is not, an exception is thrown. For information about how to create the log filters see the above sections.
$package
debug-
This will remove the log filter for the specific $package, thereby returning it to using the default log filter.
This module exports two functions:
This is just a boolean flag, so that you can write:
debug->log("This line should work") if DEBUG;
This is a lazily loaded Data::Dumper::Dumper wrapper. Why? Well, to start with, someone suggested it to me (see ACKNOWLEDGEMENTS), and secondly I realized how many times I have done this:
Data::Dumper::Dumper
use Data::Dumper; debug->log(Dumper(\%strucutre)) if DEBUG;
And how much nicer it would be if I could do this:
debug->log(Dumper(\%strucutre)) if DEBUG;
The reason we lazily load Data::Dumper is that it will take up a lot of memory, so we don't load it unless we absolutely have to. If you do not have Data::Dumper installed (for some strange reason), this function will basically return undef.
None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it. This module has been used in several production sites for over 2 years now without incident, the code released here has only been slightly modified, and documentation and tests added.
I use Devel::Cover to test the code coverage of my tests, below is the Devel::Cover report on this module test suite.
------------------------ ------ ------ ------ ------ ------ ------ ------ File stmt branch cond sub pod time total ------------------------ ------ ------ ------ ------ ------ ------ ------ debug.pm 100.0 96.4 n/a 100.0 100.0 100.0 99.3 ------------------------ ------ ------ ------ ------ ------ ------ ------ Total 100.0 96.4 n/a 100.0 100.0 100.0 99.3 ------------------------ ------ ------ ------ ------ ------ ------ ------
This module uses an all lowercase name, which is considered "wrong" by the perl-5-porters group. The idea is that all lowercase names are reserved for pragmas they create and which implement functionality missing in perl itself. I can understand their logic, and do not think that they are in the wrong in that stance. However, I do prefer to name my pragmas with lowercase names as well. That all said, I am making the choice to keep the lowercase name, and it is your choice as the user whether you want to use my module or not. I may be forcing my module to a life of obscurity by doing this, but so be it.
This module provides a simple flexible and lightweight means of logging your debug calls. If you have more sophisticated debugging/logging needs I suggest you look at Log::Log4Perl. While I have never used it myself, I have heard many good things about it.
stevan little, <stevan@iinteractive.com>
Copyright 2004-2007 by Infinity Interactive, Inc.
http://www.iinteractive.com
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install debug, copy and paste the appropriate command in to your terminal.
cpanm
cpanm debug
CPAN shell
perl -MCPAN -e shell install debug
For more information on module installation, please visit the detailed CPAN module installation guide.