NAME
Spreadsheet::Edit::Log - log method/function calls, args, and return values
SYNOPSIS
use Spreadsheet::Edit::Log qw/:DEFAULT btw btwN oops/;
sub public_method {
my $self = shift;
$self->_internal_method(@_);
}
sub _internal_method {
my $self = shift;
# Debug printing; shows location of call
btw "By the way, the zort is $self->{zort}" if $self->{debug};
btwN 2, "message"; # With location of caller's caller's caller
btwbt "message"; # With 1-line mini traceback
print colorize("Red Alert!\n", ERROR_COLOR);
# Wrapper for Carp::Confess
oops "zort not set!" unless defined $self->{zort};
my @result = (42, $_[0]*1000);
log_call \@_, [\"Here you go:", @result] if $self->{verbose};
@result;
}
...
$obj->public_method(100);
# file::lineno public_method 100 ==> Here you go:42,100000
DESCRIPTION
(This is generic, no longer specific to Spreadsheet::Edit. Someday it might become a stand-alone distribution.)
Here are possibly-overkill convenience functions for "verbose logging" and/or debug tracing of subroutine calls.
Log messages show the name of the public entrypoint called by the user, not necessarily the immediate caller of the logging function.
The call stack is searched for the nearest call to a 'public' entrypoint, which by default is a sub named starting with a lower-case letter. The is_public_api callback can be used to change this convention.
log_call {OPTIONS}, [INPUTS], [RESULTS]
Prints the result of calling fmt_call with the same arguments.
The message is written to STDERR unless a different destination is specified as described in OPTIONS or Default OPTIONS.
$msgstring = fmt_call {OPTIONS}, [INPUTS], [RESULTS]
{OPTIONS} and [RESULTS] are optional, i.e. may be entirely omitted.
A message string is composed and returned. The general form is:
File:linenum funcname input,items,... ==> output,items,...\n
or
File:linenum Obj<address>->methname input,items,... ==> output,items,...\n
[INPUTS] and [RESULTS] are each a ref to an array of items (or a single non-aref item), used to form comma-separated lists.
Each item is formatted similar to Data::Dumper, i.e. strings are "quoted" and complex structures serialized; printable Unicode characters are shown as themselves (rather than hex escapes)
... with two exceptions:
If an item is a reference to a string then the string is inserted as-is without quote, and adjacent commas are suppressed (unless the string is empty). This allows pasting arbitrary text between values.
If an item is an object (blessed reference) then only it's type and abbreviated address are shown, unless overridden via the
fmt_objectoption described below.
$string = fmt_methcall {OPTIONS}, $self, [INPUTS], [RESULTS]
A short-hand for
$string = fmt_call {OPTIONS, self => $self}, [INPUTS], [RESULTS]
log_methcall {OPTIONS}, $self, [INPUTS], [RESULTS]
A short-hand for
log_call {OPTIONS, self => $self}, [INPUTS], [RESULTS]
Note that {OPTIONS} can usualy be omitted for a more succinct form.
$frame = nearest_call {OPTIONS};
Locate the call frame for the "public" interface most recently called. This accesses the internal logic used by fmt_call, and uses the same is_public_api callback.
The result is a reference to the items returned by caller(N) which represent the call to be traced.
{OPTIONS} may be omitted.
($filename, $linenum, $subname) = abbrev_call_fn_ln_subname {OPTIONS};
Returns abbreviated information from nearest_call, possibly ambiguous but usually more friendly to humans: $filename is the basename only and $subname omits the Package:: prefix.
{OPTIONS}
- self => objref
-
If your sub is a method, your can pass
self => $selfand the the invocant will be displayed separately before the method name. To reduce clutter, the invocant is displayed for only the first of a series of consecutive calls with the sameselfvalue. - subname_override => STRING
-
STRING is shown instead of the name of the public entry-point function identified via calls to is_public_api() (which is still invoked to locate where the entry-point was called from).
Although not usually helpful, any of the "Default OPTIONS" listed next may also be included an {OPTIONS} hash passed to a specific call.
Default OPTIONS
our %SpreadsheetEdit_Log_Options = (...); in your package will be used to override the built-in defaults (but are overridden by {OPTIONS} passed in individual calls to functions which accept an OPTIONS hash).
- is_public_api => CODE
-
A callback to recognize a public entry-point.
The sub is called repeatedly with arguments
($state, [package,file,line,subname,...]).The second argument contains results from
caller(N). Your sub should return true if the frame represents the call to be described in the message.The default callback looks for any sub named with an initial lower-case letter; in other words, it assumes internal subs start with an underscore or capital letter (such as for constants). The actual code is
sub{ $_[1][3] =~ /(?:::|^)[a-z][^:]*$/ }. - fmt_object => CODE
-
Format a reference to a blessed thing, or the value of the
selfoption (if passed) whether blessed or not.The sub is called with args ($state, $thing). It should return either
$thingor an alternative representation string. By default, the type/classname is shown and an abbreviated address (seeaddrvisin Data::Dumper::Interp).$stateis a ref to a hash where you can store anything you want; it persists only during the currentfmt_callinvocation. - logdest => filehandle or *FILEHANDLE
The "logdest" option may also be set globally (affects all pacakges) by calling
set_logdest($filehandle or *FILEHANDLE)
DEBUG UTILITIES
(Not related to the log functions above, other than using logdest).
NOTE: None of these are exported by default.
btw STRING,STRING,...
btwN LEVELSBACK,STRING,STRING,...
btwbt STRING,STRING,...
Print debug trace messages. btw stands for "by the way...".
btw prints a message to STDERR (or "logdest" - see "Default OPTIONS"). preceeded by "package:linenum> " giving the location of the call to btw. A newline is appended to the message unless the last STRING already ends with a newline. The message is colorized unless $ENV{NO_COLOR} is true.
In effect, btw does what Perl's warn does when the message omits a final newline, but with a different presentation.
btwN displays the location of the call LEVELSBACK in the call stack (0 is the same as btw, 1 for your caller's location etc.)
btwbt displays an inline mini traceback before the message, like this:
main:42 ⇒ PkgA:565 ⇒ PkgB:330 ⇒ 456 ⇒ 413 : message...
The package name is omitted if it is obvious.
:btw import tag
imports all three functions (btw, btwN and btwbt).
oops STRING,STRING,...
Prepends "\n<your package name> oops:\n" to the message and then chains to Carp::confess for backtrace and death.
handlish = get_effective_logdest()
Returns the handle or glob specified in $SpreadsheetEdit_Log_Options{logdest} in your package, or if not set then the value from calling set_logdest(), or the built-in default.
COLORIZE TERMINAL TEXT
$newstring = colorize($string, SUCCESS_COLOR | WARN_COLOR | ERROR_COLOR | BOLD_COLOR);
Insert escape sequences to make the text display in an appropriate color (and turn coloring off at the end of the string), provided the process has a tty and $TERM is a terminal type which supports ansi color escapes.
The second argument indicates respectively green, yellow, red or a bold version of the default foreground color.
ENVIRONMENT VARIABLES
INCOMPATIBLE CHANGES with v1001.001
- Import tag ':btw=evalstring' no longer supported
-
This used to allow customizing the prefix part of messages from
btw, but the code grew too complicated with only imagined real benefits. -
Please use
$ENV{NO_COLOR}instead. See https://no-color.org/
SEE ALSO
AUTHOR
Jim Avera (jim.avera gmail)
LICENSE
Public Domain or CC0