Paranoid::Debug(3pm)

πŸ“¦
version 2.10 Β· 3 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

πŸ’– Paranoid::Debug πŸ’–

hey bestie, welcome to Paranoid::Debug β€” it's a Perl module from the User Contributed Perl Documentation collection, and it's literally here to make your paranoid lil programs spill the tea about what they're doing. πŸ’…

✨ VERSION ✨

$Id: lib/Paranoid/Debug.pm, 2.10 2022/03/08 00:01:04 acorliss Exp $


🌸 SYNOPSIS 🌸

okay so this is how you actually use it, no cap:

use Paranoid::Debug;

PDEBUG        = 1;
PDMAXINDENT   = 40;
PDPREFIX      = sub { scalar localtime };
pdebug("starting program", PDEBUG1);
foo();

# New method
sub foo {
  my $foo = shift;
  my @bar = shift;
  my $rv;

  subPreamble(PDEBUG1, '$@', $foo, @bar);

  # Miscellaneous code...
  pdebug("someting happened!", PDEBUG2);

  # More miscellaneous code...

  subPostamble(PDEBUG1, '$', $rv);

  return $rv;
}

# Old method
sub foo {
  my $foo = shift;
  my @bar = shift;
  my $rv;

  pdebug('entering w/(%s)(%s)', PDEBUG1, $foo, @bar);
  pIn();

  # Miscellaneous code...
  pdebug("someting happened!", PDEBUG2);

  # More miscellaneous code...

  pOut();
  pdebug('leaving w/rv: %s', PDEBUG1, $rv);

  return $rv;
}

pderror("error msg");

πŸ¦‹ DESCRIPTION πŸ¦‹

the whole point of this module is giving you a genuinely useful lil framework for spitting out debugging output. ✨ you slap a level of detail on your pdebug statements, and they only show up on STDERR when PDEBUG is set to that level or higher. so your program can be as chatty or as mysterious as you want, depending on the vibe. πŸ’…

and when you use the subPreamble and subPostamble functions at the start and end of every function? the debugging output gets indented all cute and nested so you can literally see how deep your recursion is going. it's giving call-stack vision. πŸ‘‘

NOTE: every single module in the Paranoid framework uses this module. their debug levels start at 9 and go up. so you should use 1 - 8 for your own modules or code. PDEBUG1 - PDEBUG8 exist for exactly that. 🫢

πŸŽ€ IMPORT LISTS πŸŽ€

by default this module exports these symbols:

PDEBUG pdebug pIn pOut subPreamble subPostamble PDEBUG1 .. PDEBUG8

and these specialized import lists also exist:

List        Members
--------------------------------------------------------
constants   PDEBUG1 PDEBUG2 PDEBUG3 PDEBUG4 PDEBUG5
            PDEBUG6 PDEBUG7 PDEBUG8
all         @defaults @constants
            pderror PDPREFIX PDLEVEL1 PDLEVEL2
            PDLEVEL3 PDLEVEL4 PDMAXINDENT

πŸ’œ CONSTANTS πŸ’œ

PDEBUG1 .. PDEBUG8

eight constants, exported by default, for developers who wanna have up to eight levels of diagnostic output. πŸ“ and bestie, listen: none of these levels are used by internal Paranoid code β€” they're all reserved for third parties. they're yours. go wild.

PDLEVEL1 .. PDLEVEL4

these are not meant for other modules to use. they exist for the internal debug levels that all Paranoid::* modules rely on. they're all higher than what PDEBUG* gives you, so devs get max control over their own verbosity but the Paranoid diagnostics don't add unwanted noise. immaculate boundary-setting tbh. πŸ™ˆ


πŸ’… SUBROUTINES/METHODS πŸ’…

PDEBUG

PDEBUG is an lvalue subroutine that starts out set to 0, but you can set it to any positive integer. higher number = more pdebug statements get printed. simple as. ✨

PDPREFIX

PDPREFIX = sub {

    # Old default Prefix to use with debug messages looks like:
    #
    #   [PID - $dlevel] Subroutine:
    #
    my $caller      = shift;
    my $indentation = shift;
    my $oi          = $indentation;
    my $maxLevel    = PDMAXINDENT;
    my $prefix;

    # Cap indentation
    $indentation = $maxLevel if $indentation > $maxLevel;

    # Construct the prefix
    $prefix = ' ' x $indentation . "[$$-$oi] $caller: ";

    return $prefix;
    };

PDPREFIX is an lvalue subroutine holding a code reference to a subroutine that hands back an appropriate prefix for debug messages. the default one prints an indented string (indented by how deep you are on the call stack) showing the process PID, the debug level, and the current routine or method that pdebug was called in. iconic formatting, honestly. 🌈

PDMAXINDENT

PDMAXINDENT is an lvalue subroutine that starts at 40, but can be set to any integer. it controls the max indentation of debug messages. because bestie β€” indenting a debug message a hundred columns deep on an eighty column terminal just because your stack got deep? that's not it. πŸ’€

pderror

pderror("error msg");

this one prints the message you pass it straight to STDERR. 🫢

pdebug

pdebug("debug statement", PDEBUG3);
pdebug("debug statement: %s %2d %.3f", PDEBUG3, @values);

you call this with one mandatory argument (the string to print) and an optional integer. that integer gets compared against PDEBUG, and the debug statement prints if PDEBUG is equal to it or higher. ✨

the return value is always the debug statement itself, which means one single statement can both produce debug output and set variables. for instance:

Paranoid::ERROR = pdebug("Something bad happened!", PDEBUG3);

as an added benefit you can pass a printf template along with the values and they get handled appropriately. any string value passed as undef gets replaced with the literal string "undef". πŸŽ€

one deviation from printf: you can specify a placeholder that gobbles up any number of extra arguments while still doing the "undef" substitution:

pdebug("I was passed these values: %s", 3, @values);

pIn

pIn();

this makes all subsequent pdebug messages indent by one additional space. πŸ“

pOut

pOut();

this makes all subsequent pdebug messages indent by one less space. reverse uno. πŸ¦‹

subPreamble

subPreamble(PDEBUG1, '$@', @_);

this combines the functionality of pdebug and pIn to mark the entry point into a given function. it also gives you a convenient summarization function so you don't log ridiculously long arguments into your diagnostic output. no one needs that novel in their logs. πŸ’€

the second argument is essentially whatever a valid subroutine prototype would be for your function (check out Prototypes in perlsub(3) for more examples). and in addition to the standard prototypes, p is supported as a prototype too! it's basically the same as a scalar prototype, except instead of printing a summarized excerpt of its contents, it replaces all characters with * characters. so anything sensitive β€” passwords, secrets, whatever β€” should use p instead of $. protect the goods, bestie. πŸ”’

summarization works like this: any scalar value (excluding references of any kind) longer than 20 characters gets truncated to 20 characters, and then has the full number of bytes appended. lists just report how many elements are in the array, and hashes list the number of key/value pairs in the hash. every other type gets passed as-is.

indentation is adjusted after the initial summarized message. ✨

subPostamble

subPostamble(PDEBUG1, '$', $rv);

works exactly the same as subPreamble, except indentation happens in reverse order. the prototype should reflect the prototype of the returned value, not the function arguments. indentation gets set back prior to the summarized message being printed. 🎯


🌟 DEPENDENCIES 🌟

  • Paranoid
  • Carp

πŸ“ BUGS AND LIMITATIONS πŸ“

pderror (and by extension, pdebug) will generate errors if STDERR is closed elsewhere in the program. so like… don't do that. or do, and enjoy the chaos. 😭


πŸ‘‘ AUTHOR πŸ‘‘

Arthur Corliss (corliss@digitalmages.com)


this software is free software. similar to Perl, you can redistribute it and/or modify it under the terms of either:

  1. the GNU General Public License <https://www.gnu.org/licenses/gpl-1.0.html> as published by the Free Software Foundation <http://www.fsf.org/>; either version 1 <https://www.gnu.org/licenses/gpl-1.0.html>, or any later version <https://www.gnu.org/licenses/license-list.html#GNUGPL>, or
  2. the Artistic License 2.0 <https://opensource.org/licenses/Artistic-2.0>,

subject to the following additional term: no trademark rights to "Paranoid" have been or are conveyed under any of the above licenses. however, "Paranoid" may be used fairly to describe this unmodified software, in good faith, but not as a trademark.

(c) 2005 - 2020, Arthur Corliss (corliss@digitalmages.com) (tm) 2008 - 2020, Paranoid Inc. (www.paranoid.com)


and that's the whole page, bestie!! πŸŽ€ this was rendered by perl v5.38.2 on 2024-03-07, and yeah it's been sitting in the Paranoid::Debug(3pm) section of the manual this whole time. go forth and debug with main character energy. πŸ’–βœ¨

πŸ“¦ where this page comes from