Debug::Statements - provides an easy way to insert and enable/disable debug statements.
The d() function prints the name of the variable AND its value.
d()
This implementation been optimized to minimize your keystrokes.
my $myvar = 'some value'; my @list = ('zero', 1, 'two', "3"); my %hash = ('one' => 2, 'three' => 4); use Debug::Statements; my $d = 1; d "Hello world"; d '$myvar'; d '@list %hash';
DEBUG sub mysub: Hello world DEBUG sub mysub: $myvar = 'some value' DEBUG sub mysub: @list = [ 'zero', 1, 'two', '3' ] DEBUG sub mysub: %hash = { 'one' => 2, 'three' => 4 }
"The most effective debugging tool is still careful thought, coupled with judiciously placed print statements" - Brian Kernighan, Unix for Beginners (1979)
Familiarity - everyone has used them.
When strategically placed, they show the values of key variables as well as the flow of control.
May be left in the code to facilitate debugging, when the code next needs to be enhanced.
May be turned on to help remotely debug problems.
Printing the names of executing subroutines can be particularly useful when debugging large unfamiliar programs produced by multiple developers over the span of years.
Can be used in conjuction with a debugger, which can be used to change variables on-the-fly, step into libraries, or skip/repeat sections of code
If the results are saved to a file, file comparisons can be useful during regression testing.
my $d = 1; my $myvar = 'some value'; if ($d) { print "DEBUG sub xyz: \$myvar is $myvar\n" } use Dumpvalue; if ($d) { print "\nDEBUG: Dumping \@list:\n"; Dumpvalue->new->dumpValue(\@list) } if ($d) { print "\nDEBUG: Dumping \%hash:\n"; Dumpvalue->new->dumpValue(\%hash) }
Tedious, require many keystrokes to type
Reduces readability of the source code.
Print statements clutter the standard output
Need to be removed or commented out later
If some statements are mistakenly left in, the output can cause problems or confusion
The next time the code needs to be enhanced, any removed print statements need to be re-inserted or uncommented
Debug::Statements::d() provides an easy way to insert and enable/disable debug statements.
Debug::Statements::d()
my $myvar = 'some value'; use Debug::Statements; my $d = 1; d '$myvar';
DEBUG sub mysub: $myvar = 'some value'
This is all you need to know to get started.
d '@list'; d '$list[2]'; d '$list[$i]'; d '%hash'; d '$nestedhash{key}'; d '$nestedhash{$key1}{$key2}'; d '$listref'; d '$arrayref'; d '$arrayref->[2]'; d '$hashref->{key}'; d '$hashref->{$key}';
d 'Processing...'; d "This comment prints the value of a variable: $myvar";
use Debug::Statements qw(d d2 d0 D); my $d = 1; d '$myvar'; # prints d2 '$myvar'; # does not print since $d < 2 $d = 2; d '$myvar'; # prints d2 '$myvar'; # prints D '$myvar'; # always prints, even if $d is 0 or undef # this is useful for short term debugging # of existing code d0 '$myvar'; # same as D
d '\n $myvar'; d '\n$myvar\n\n'; d '\n-------\n@list\n--------\n';
d '$myvar $myvar2 $myvar3'; or d '$myvar,$myvar2,$myvar3'; or d '$myvar, $myvar2, $myvar3'; or d '($myvar, $myvar2, $myvar3)';
Each of these examples prints one line each for $myvar, $myvar2, and $myvar3
d('$myvar');
Options may be specifed with an 2nd argment to d()
b print suBroutine name (on by default)
c Chomp newline before printing, useful when printing captured $line from a parsed input file
e print # of Elements contained in top level of the array or hash
n print line Number $. of the input file
q treat the string as text, do not try to evaluate it. This is useful if you are parsing another Perl script, and the text contains sigil characters $@%
$@%
r tRuncate output (defaults to 10 lines)
s Sort contents of arrays (hashes are always sorted)
t print Timestamp using localtime() and Time::HiRes::gettimeofday()
localtime()
Time::HiRes::gettimeofday()
x die when code reaches this line
z compress array and hash dumps to save screen space
To print $line chomped and with line number and timestamp
d('$line', 'cnt');
To print %hash in a compressed format
d('%hash', 'z');
To negate an option, capitialize it (use 'B' instead of 'b')
Options are only valid for the current debug statement
To make the current options global (peristent), append a star *
For example, to set timestamp globally
d('$var', 't*');
For example, to unset timestamp globally
'$var', 'T*');
PadWalker must be installed
In addition, the test suites require Test::Fatal, Test::More, and Test::Output
Your code must have a variable '$d' defined to enable the debug statements
Exception: D() does not require the $d variable to exist. It always prints. See "Multiple debug levels" above.
D()
$d was chosen because it is easy to type and intuitive
If your code already uses '$d' for another purpose, this can be changed with Debug::Statements::setFlag()
Debug::Statements::setFlag()
Your code must not already contain a local subroutine called 'd()', since this function is imported
Consider enabling $d through the command line of your script
use Getopt::Long; my %opt; my $d = 0; GetOptions( \%opt, 'd' => sub{$d=1}, 'dd' => sub{$d=2}, ... );
This provides an easy way for others to set your code into debug mode. They can then capture stdout and email it to you.
Calls to d() should use 'single quotes' instead of "double quotes"
Exception: To produce custom output, call d() with double-quotes. As is always the case with double-quotes in Perl, variables will be interpolated into values before entering the d() subroutine.
d "Found pattern: $mynum in file $filename";
DEBUG sub mysub: Found pattern asdf in file foo.txt
d "Found $key and replaced with $subtable_ref->{$key} on: $line"
DEBUG sub mysub: Found foo and replaced with bar on: foobar
Remember that when using escaped \$ \@ \% within "double quotes", this is equivalent to using $ @ % within 'single quotes'
This means that d() will try to print the names and values of those variables.
The module includes functions which affect global operation
Debug::Statements::enable(); # enable operation (default) Debug::Statements::disable(); # disable operation, even if $d >= 1 Debug::Statements::setFlag('$yourvar'); # default is '$d' Debug::Statements::setPrintDebug(""); # default is "DEBUG: " Debug::Statements::setTruncate(10); # default is 10 lines
Not supported
Array slices such as $listvar[1:3]
$listvar[1:3]
Some special variables such as $1 $_ @_ ...but any of these can be printed by using "double quotes", since this will cause Perl to evaluate the expression before calling d(). For example d "@_"
$1 $_ @_
The evaluation is of variables does not support the full range of Perl syntax. Most cases work, for example: d '$hash{$key}' However hashes used as hash keys will not work, for example: d '$hash{$hash2{$key}}' As a workaround, use "double quotes": d "\$hash{$hash2{$key}}" instead. The rule is similar for arrays
d '$hash{$key}'
d '$hash{$hash2{$key}}'
d "\$hash{$hash2{$key}}"
ls() is also provided for convenience, but not exported by default
use Debug::Statements qw(d d0 d1 d2 d3 D ls); ls($myfilename);
When $d >= 1, prints an ls -l listing of $myfilename.
Note that ' ' is not used inside ls()
This module has been tested on
Linux 5.8.6, 5.8.8, 5.12, 5.14, and 5.20
It will probably work as far back as 5.8.0
Windows 5.20
PadWalker::peek_my() gets the value of $d and the contents of your variables (from outside its scope!) The variable values are stored in an internal hash reference
PadWalker::peek_my()
It does NOT change the values of your variables.
caller()[3] gets the name of subroutine which encloses your code
caller()[3]
Data::Dumper pretty-prints the contents of your variable
Data::Dumper
For performance-critical applications, frequent calls to PadWalker::peek_my() and caller() may be too intensive
caller()
Globally disable all functionality by calling Debug::Statements::disable(); The PadWalker and caller functions will not be called. Debug statements will not be printed.
Debug::Statements::disable();
OR comment out some of your calls to d() within performance-critical loops
OR completely disable this code is to define you own empty d() subroutines.
#use Debug::Statements qw(d d2); sub d{}; sub d2{};
Chris Koknat 2018 chris.koknat@gmail.com
This software is copyright (c) 2013-18 by Chris Koknat.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Debug::Statements, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Debug::Statements
CPAN shell
perl -MCPAN -e shell install Debug::Statements
For more information on module installation, please visit the detailed CPAN module installation guide.