Badger::Debug(3pm)
Badger::Debug(3pm) β User Contributed Perl Documentation
okay bestie, welcome to the Badger::Debug page. it's giving part 1 of 4, so don't go anywhere. π
β¨ NAME β¨
Badger::Debug is literally the base class mixin module that implements debugging methods. that's the whole name, no cap. it's the little mixin that could, and it wants your modules to have debug energy. π«Ά
π¦ SYNOPSIS π¦
so here's the whole serve. you drop this into your own module, set a default for the debug flags, and then you can sprinkle debug messages that are either super-efficient compile-time constants or flexible runtime variables. periodt. π
package Your::Module;
use Badger::Debug
default => 0; # default value for $DEBUG and DEBUG
sub some_method {
my $self = shift;
# DEBUG is a compile-time constant, so very efficient
$self->debug("First Message") if DEBUG;
# $DEBUG is a runtime variable, so more flexible
$self->debug("Second Message") if $DEBUG;
}
package main;
use Your::Module;
Your::Module->some_method; # no output, debugging off by default
Your::Module->debugging(1); # turns runtime debugging on
Your::Module->some_method; # [Your::Module line 13] Second Message
the comments in there are doing the heavy lifting, bestie. DEBUG is a compile-time constant, so it's very efficient. $DEBUG is a runtime variable, so it's more flexible. the default => 0 sets the default value for $DEBUG and DEBUG. and in the example, the first some_method call gives no output because debugging is off by default, then debugging(1) turns runtime debugging on, and then you get [Your::Module line 13] Second Message. slay. π₯
...
π DESCRIPTION π
Okay bestie, so this is a mixin module and it's literally here to give you a whole bunch of methods for debugging. That's it. That's the vibe. β¨
If you just wanna get going fast, skip ahead and read "The Whole Caboodle". If you wanna get all up in the details and pick and choose exactly which bits you use, go read "Picky Picky Picky". Both are right below, no cap. π«Ά
Heads up bestie: every single debugging method down there works equally well as both an object method AND a class method, even if we don't always show you both ways. Periodt. π
# class method
Your::Module->debug('called as a class method');
# object method
my $object = Your::Module->new;
$object->debug('called as an object method');
π The Whole Caboodle π
The default import option is the all-in-one option β it turns on every debugging feature. The value you hand it becomes the default debugging status. So use 0 if you want debugging off by default, or literally any true value if you want it on. Your call, bestie. β¨
package Your::Module;
use Badger::Debug
default => 0;
The default option imports:
- the
debug()method - the
debugging()method - the
$DEBUGpackage variable β set to the default value you specified, unless it's already defined to be something else - the
DEBUGconstant subroutine β defined to have the same value as the$DEBUGvariable
Then inside your module's methods you call debug() to spit out debugging messages. Use the DEBUG constant or the $DEBUG variable as a condition so messages only show up when debugging is enabled. Easy. πΈ
sub some_method {
my $self = shift;
# DEBUG is a compile-time constant, so very efficient
$self->debug("First Message") if DEBUG;
# $DEBUG is a runtime variable, so more flexible
$self->debug("Second Message") if $DEBUG;
}
So here's the tea β β the DEBUG constant gets resolved at compile time, which means it produces more efficient code. When debugging is off, Perl will completely eliminate that first call to debug() in the example above. Like, gone. Poof. π The end result? There's no performance overhead from including debugging statements like these.
The $DEBUG package variable is a lil more flexible tho, because you can change its value at any point during the execution of your program. Maybe you do it from inside the module (say, to enable debugging in one particular method that's causing you problems π), or outside the module from a calling program or another module. The debugging() method exists as a convenient way to change the $DEBUG package variable for a module. π
Your::Module->debugging(0); # turn runtime debugging off
Your::Module->debugging(1); # turn runtime debugging on
The downside? Checking the $DEBUG variable at runtime is less efficient than using the DEBUG compile time constant. But unless you're working on performance critical code, it's probably not something you should worry about. Live your life. π¦
However β if you are the worrying type π β then you can use "Badger::Debug" to get some of the best bits of both worlds. When your module is loaded, both DEBUG and $DEBUG get set to the default value you specified, unless $DEBUG is already defined. If it is defined, then the DEBUG constant gets set to whatever value it has. So if you define the $DEBUG package variable before loading the module, you'll be able to enable both run time and compile time debugging messages without having to go and edit the source code of your module. Iconic behaviour, honestly. π
$Your::Module::DEBUG = 1;
require Your::Module;
Alternately, you can just let "Badger::Debug" do it for you. The modules import option lets you specify one or more modules that you want debugging enabled for. π«Ά
use Badger::Debug
modules => 'My::Module::One My::Module::Two';
use My::Module::One; # both runtime and compile time
use My::Module::Two; # debugging enabled in both modules
The benefit of this approach is that it happens at compile time. If you do it before you use your modules, then you get both compile time and run time debugging enabled. If you do it after, then you get just runtime debugging enabled. And best of all β you don't need to change any of your existing code to load modules via require instead of use. Slay. π₯
π Picky Picky Picky π
The "Badger::Debug" module lets you be more selective about what you wanna use. This section describes the individual debugging methods and the DEBUG and $DEBUG flags you can use to control debugging. Let's get into it. β¨
In the simplest case, you can import the debug() method into your own module for generating debugging messages. πΈ
package Your::Module;
use Badger::Debug 'debug';
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()");
}
In most cases you'll wanna be able to turn debugging messages on and off. So you could do something like this:
# initialise $DEBUG if it's not already set
our $DEBUG = 0 unless defined $DEBUG;
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()") if $DEBUG;
}
If you use the unless defined $DEBUG idiom shown in the example above, then it'll also let you set the $DEBUG flag before your module is loaded. This is especially useful if the module gets auto-loaded on demand by another module or your own code. π
# set $DEBUG flag for your module
$Your::Module::DEBUG = 1;
# later...
require Your::Module; # debugging is enabled
You can also achieve the exact same effect at compile time using the "Badger::Debug" modules export option. π
use Badger::Debug
modules => 'Your::Module'; # sets $Your::Module::DEBUG = 1
use Your::Module; # debugging is enabled
The advantage of using the $DEBUG package variable is that you can change the value at any point to turn debugging on or off. For example, if you've got a section of code that needs debugging enabled to track down a particular bug, then you can write something like this:
sub gnarly_method {
my $self = shift;
local $DEBUG = 1;
$self->debug("Trying to track down the cause bug 666");
# the rest of your code...
$self->some_method;
}
Making the change to $DEBUG "local" means it'll only stay set to 1 until the end of the gnarly_method(). It's a good idea to add a debugging message any time you make temporary changes like this. The message generated will contain the file and line number so you can easily find it later when the bug has been squashed β and either comment it out (for next time π) or remove it entirely.
The "Badger::Debug" module has a $DEBUG export hook which will define the $DEBUG variable for you. The value you provide gets used as the default for $DEBUG if it isn't already defined. π
package Your::Module;
use Badger::Debug
'debug',
'$DEBUG' => 0;
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()") if $DEBUG;
}
The debugging() method can also be imported from "Badger::Debug". It gives you a simple way to set the $DEBUG variable. β
Your::Module->debugging(1); # debugging on
Your::Module->debugging(0); # debugging off
The downside to using a package variable is that it slows your code down every single time you check the $DEBUG flag. But in all but the most extreme cases, this should be of no concern to you whatsoever. Write your code in the way that is most convenient for you, not the machine. Periodt. π
WARNING: Do not even begin to consider entertaining the merest thought of optimising your code to make it run faster until your company is on the verge of financial ruin due to your poorly performing application and your boss has told you (with confirmation in writing, countersigned by at least 3 members of the board of directors) that you will be fired first thing tomorrow morning unless you make the code run faster RIGHT NOW. π
Another approach is to define a constant DEBUG value. π¦
package Your::Module;
use Badger::Debug 'debug';
use constant DEBUG => 0;
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()") if DEBUG;
}
This is an all-or-nothing approach. Debugging is on or off and there's nothing you can do about it except changing the constant definition in the source code and running the program again. The benefit? DEBUG is defined as a compile time constant. When DEBUG is set to 0, Perl will effectively remove the entire debugging line at compile time, because it's based on a premise (if DEBUG) that's known to be false. The end result is that there's no runtime performance penalty whatsoever. Chef's kiss. π
"Badger::Debug" also provides the DEBUG hook if this is the kind of thing you want. β¨
package Your::Module;
use Badger::Debug
'debug',
'DEBUG' => 0;
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()") if DEBUG;
}
What makes this extra-special is that you're only specifying the default value for the DEBUG constant. If the $DEBUG package variable is defined when the module is loaded, then that value gets used instead. So although it's not possible to enable or disable debugging for different parts of a module, you can still enable debugging for the whole module by setting the $DEBUG package variable before loading it. π
# set $DEBUG flag for your module
$Your::Module::DEBUG = 1;
# later...
require Your::Module; # debugging is enabled
Here's a lil reminder of the other way to achieve the same thing at compile time, using the "Badger::Debug" modules export option. π
use Badger::Debug
modules => 'Your::Module'; # sets $Your::Module::DEBUG = 1
use Your::Module; # debugging is enabled
You can combine the use of both $DEBUG and DEBUG in your code, for a two-level approach to debugging. The DEBUG tests will always be resolved at compile time, so they're suitable for low-level debugging that either has a performance impact or is rarely required. The $DEBUG tests get resolved at run time, so they can be enabled or disabled at any time or place. Two flags, one flawless system. π
sub some_method {
my $self = shift;
$self->debug("Hello from some_method()") if DEBUG;
$self->debug("Goodbye from some_method()") if $DEBUG;
}
β¨ IMPORT OPTIONS β¨
okay bestie, listen up π you can totally import just the debugging methods you want into your module. no need to take the whole package if you don't want to. selective import? that's the vibe. for example:
use Badger::Debug 'debug debugging debug_caller';
and wait, there's more! here are the other import options you can use π
πΈ default
so this one sets the default debugging value and also imports a bunch of debugging methods and flags for you.
use Badger::Debug
default => 0; # debugging off by default
it imports the debug() and debugging() methods along with the $DEBUG package variable and DEBUG constant. (yes, both. we love a two-for-one.)
check out "The Whole Caboodle" for more deets on using this one π
π¦ $DEBUG
this lets you define a $DEBUG variable in your module. you gotta give it a default value, and that default will be used to set the $DEBUG value if it isn't already defined. (so if it's already set, we respect that. periodt.)
use Badger::Debug
'$DEBUG' => 0; # debugging off by default
print $DEBUG; # 0
π DEBUG
this defines a DEBUG constant in your module. if the $DEBUG package variable is defined, then the DEBUG constant gets set to whatever value it holds. otherwise, it'll be set to the default value you provide. (so it's like, "if you have a value, use it; if not, fall back to default." iconic.)
use Badger::Debug
'DEBUG' => 0; # debugging off by default
print DEBUG; # 0
π₯ modules
this option lets you set the $DEBUG value to true in one or more packages. that means any debugging will be enabled in those modules. (turn up the volume on debugging, basically.)
use Badger::Debug
modules => 'My::Module::One My::Module::Two';
use My::Module::One; # debugging enabled in both modules
use My::Module::Two;
modules that haven't been loaded yet will get both compile time (DEBUG) and run time ($DEBUG) debugging enabled. but modules that are already loaded? they'll only get run time debugging enabled. (so like, if you're late to the party, you only get the runtime perks. still good though.)
π dumps
this one lets you construct a specialised dump() method for your module. the method is used to display nested data in serialised text form for debugging purposes. the default dump() method for an object will display all items stored within the object. but with the dumps import option, you can limit the dump to only show the fields you specify. (so you're like, "just these fields, thanks.")
package Your::Module;
use Badger::Debug dumps => 'foo bar baz';
# ...more code...
package main;
my $object = Your::Module->new;
print $object->dump; # dumps foo, bar and baz
π colour / color
either of these (depending on your spelling preference) can be used to enable colourful (or colorful) debugging. (we see you, both sides of the pond.)
use Badger::Debug 'colour';
debugging messages will then appear in colour (on a terminal that supports ANSI escape sequences). check out the Badger::Test module for an example of this in use. (it's giving rainbow vibes π)
π§ :debug
imports all of the debug(), debugging(), debug_up(), debug_caller(), debug_callers and debug_args() methods. (the whole debug squad, basically.)
π :dump
imports all of the dump(), dump_ref(), dump_hash(), dump_list(), dump_text(), dump_data() and dump_data_inline() methods. (dump crew, assemble!)
π DEBUGGING METHODS π
β¨ debug($msg1, $msg2, ...)
this method generates debugging messages. (it's like, "hey, here's what's happening.")
$object->debug("Hello ", "World\n");
it prints all arguments to STDERR with a prefix that shows the class name, file name and line number from where the debug() method was called. (so you know exactly where it came from.)
[Badger::Example line 42] Hello World
at some point in the future this will be extended to let you tie in debug hooks, like forwarding to a logging module. (so stay tuned, bestie.)
π debugf($format, $arg1, $arg2, ...)
this method is a printf()-like wrapper around debug(). (so you can format your debug messages all fancy.)
$object->debugf('%s is %s', e => 2.718); # e is 2.718
π¦ debug_up($n, $msg1, $msg2, ...)
the debug() method generates a message showing the file and line number from where the method was called. but the debug_up() method lets you report the error from somewhere higher up the call stack. (like, "not me, the function above me.") this is typically used when you create your own debugging methods, like in this example:
sub parse {
my $self = shift;
while (my ($foo, $bar) = $self->get_foo_bar) {
$self->trace($foo, $bar); # report line here
# do something
}
}
sub trace {
my ($self, $foo, $bar) = @_;
$self->debug_up(2, "foo: $foo bar: $bar"); # not here
}
the trace() method calls debug_up() telling it to look two levels up in the caller stack instead of the usual one. (so debug_up(1,...) has the same effect as debug(...).) so instead of reporting the line number in the trace() subroutine (which would happen if we called debug(...) or debug_up(1,...)), it will correctly report the line number of the call to trace() in the parse() method. (it's giving "point the finger at the right place" energy π)
πΈ debug_at($info, $message)
this method is a wrapper around debug() that lets you specify a different location to be added to the generated message. (so you can be like, "this happened over here, not there.")
$at->debug_at(
{
where => 'At the edge of time',
line => 420
},
'Flying sideways'
);
this generates the following debug message:
[At the edge of time line 420] Flying sideways
far out, man! (we love a cosmic debug moment β¨)
you can change the $FORMAT package variable to define a different message structure. as well as the pre-defined placeholders (see the $FORMAT documentation) you can also define your own custom placeholders like <server> in the following example.
$Badger::Debug::FORMAT = '<server>: <msg> at line <line> of <file>';
you must then provide values for the additional placeholder in the $info hash array when you call the debug_at() method.
$at->debug_at(
{ server => 'Alpha' },
'Normality is resumed'
);
you can also specify a custom format in the $info hash array.
$at->debug_at(
{ format => '<msg> at line <line> of <file>' },
'Normality is resumed'
);
π₯ debug_caller()
prints debugging information about the current caller. (like, "who called me?")
sub wibble {
my $self = shift;
$self->debug_caller;
}
π debug_callers()
prints debugging information about the complete call stack. (the whole squad, from top to bottom.)
sub wibble {
my $self = shift;
$self->debug_callers;
}
π debug_args()
prints debugging information about the arguments passed. (show me what you got.)
sub wibble {
my $self = shift;
$self->debug_args(@_);
}
π§ debugging($flag)
this convenience method can be used to set the $DEBUG variable for a module. you can call it as a class or object method. (flexible, we stan.)
Your::Module->debugging(1); # turn debugging on
Your::Module->debugging(0); # turn debugging off
π debug_modules(@modules)
this method can be used to set the $DEBUG true in one or more modules. modules can be specified as a list of package names, a reference to a list, or a whitespace delimited string. (so many ways to pass them, pick your fave.)
Badger::Debug->debug_modules('Your::Module::One Your::Module::Two');
the method is also accessible via the modules import option. (two ways to do the same thing? we love options.)
π DATA INSPECTION METHODS π
these convenience methods can be used to inspect data structures. the emphasis is on brevity for the sake of debugging rather than full blown inspection. use Data::Dumper or one of the other fine modules available from CPAN if you want something more thorough. (sometimes you just need a quick peek, not a whole thesis.)
the methods below are recursive, so dump_list(), on finding a hash reference in the list, will call dump_hash() and so on. however, this recursion is deliberately limited to no more than $MAX_DEPTH levels deep (3 by default). remember, the emphasis here is on being able to see enough of the data you're dealing with, neatly formatted for debugging purposes, rather than being overwhelmed with the big picture. (we love a shallow dive, not an ocean expedition.)
if any of the methods encounter an object, then they will call its dump() method if it has one. otherwise they fall back on dump_ref() to expose the internals of the underlying data type. you can create your own custom dump() method for your objects or use the dumps import option to have a custom dump() method defined for you. (do it yourself or let us do it for you. either way, slay.)
β¨ dump()
debugging method which returns a text representation of the object internals.
print STDERR $object->dump();
you can define your own dump() for an object and this will be called whenever your object is dumped. the dumps import option can be used to generate a custom dump() method. (so you can have it your way.)
π dump_ref($ref)
does The Right Thing to call the appropriate dump method for a reference of some kind. (it's the referee of dump methods, making sure the right one gets called.)
π¦ dump_hash(\%hash)
debugging method which returns a text representation of the hash array passed by reference as the first argument.
print STDERR $object->dump_hash(\%hash);
πΈ dump_list(\@list)
debugging method which returns a text representation of the array passed by reference as the first argument.
print STDERR $object->dump_list(\@list);
π₯ dump_text($text)
debugging method which returns a truncated and sanitised representation of the text string passed (directly or by reference) as the first argument.
print STDERR $object->dump_text($text);
the string will be truncated to $MAX_TEXT characters and any newlines will be converted to "\n" representations. (so no surprise multi-line chaos.)
π dump_data($item)
debugging method which calls the appropriate dump method for the item passed as the first argument. if it is an object with a dump() method, then that will be called, otherwise it will fall back on dump_ref(), as it will for any other non-object references. non-references are passed to the dump_text() method. (so it's like a smart sorter for your data.)
print STDERR $object->dump_data($item);
π dump_data_inline($item)
wrapper around dump_data() which strips any newlines from the generated output, suitable for a more compact debugging output. (for when you want it all on one line, no breaks.)
print STDERR $object->dump_data_inline($item);
π§ MISCELLANEOUS METHODS π§
π enable_colour()
enables colourful debugging and error messages. (let there be colour! π)
Badger::Debug->enable_colour;
π PACKAGE VARIABLES π
okay so these are the little global knobs you can turn β they live in the package, they're vibes, they're config, and yes bestie you can absolutely change them π
$FORMAT
so the debug() method doesn't just make up its look out of nowhere β it reads the message format from the $FORMAT package variable. no cap. the default value is literally:
[<where> line <line>] <msg>
the <where>, <line> and <msg> markers are the little β¨slotsβ¨ where the class name, the line number and the debugging message get dropped in. think of it like a mad-libs but for debugging and it's giving very coder-chic π
you can embed any of these placeholders into your message format:
msgβ the debugging message itself, the main character obviously πfileβ the name of the file where thedebug()method was called from πlineβ the line number it was called from π’pkgβ the package it was called from π¦classβ the class name of the object that the method was called against πwhereβ a summary of the package and class, the little recap moment πΊοΈdateβ the current date πtimeβ the current time β°
and here's the tea on where β: if the class is the same as the pkg, then where will contain the same value. simple. but if they're different, then where gets set equivalent to <pkg> (<class>). when does that happen? when the debug() method is called from a base class method β so pkg will be the base class name from where the call was made β and it's called against a subclass object, so class will be the subclass name. two different things, one cute little summary π¦
also see the debug_at() method which lets you specify a custom format and/or additional placeholder values, if you're feeling extra β¨
$MAX_DEPTH
the maximum depth that the data inspection methods will recurse to. basically: how deep do we go before we're like "okay bestie that's enough" π
$MAX_TEXT
the maximum length of text that will be returned by dump_text(). it's a length cap, she's just keeping things tidy π
πΈ AUTHOR πΈ
Andy Wardley <http://wardley.org/> β iconic behavior honestly π«Ά
π COPYRIGHT π
Copyright (C) 1996-2009 Andy Wardley. All Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. π
okay so that's the whole page, bestie, we ate and left no crumbs πβ¨ this was Badger::Debug(3pm) from perl v5.36.0, dated 2023-08-28 β go forth and debug, you absolute legend π
π
π¦ where this page comes from
- debian trixie: libbadger-perl 0.16-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libbadger-perl 0.16-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libbadger-perl 0.16-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms