The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Spreadsheet::Edit::Log - log method/function calls, args, and return values

SYNOPSIS

  use Spreadsheet::Edit::Log qw/:DEFAULT btw oops/;

  sub public_method {
    my $self = shift;
    $self->_internal_method(@_);
  }
  sub _internal_method {
    my $self = shift;

    oops "zort not set!" unless defined $self->{zort};
    btw "By the way, the zort is $self->{zort}" if $self->{debug};

    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 be published as a stand-alone distribution rather than packaged in Spreadsheet-Edit.)

This provides perhaps-overkill convenience for "verbose logging" and/or debug tracing of subroutine calls.

The resulting message string includes the location of the user's call, the name of the public function or method called, and a representation of the inputs and outputs.

The "public" function/method name shown is not necessarily the immediate caller of the logging function.

log_call {OPTIONS}, [INPUTS], [RESULTS]

Prints the result of calling fmt_call with the same arguments.

The message is written to STDERR unless logdest => FILEHANDLE is included in OPTIONS.

$msgstring = fmt_call {OPTIONS}, [INPUTS], [RESULTS]

{OPTIONS} and [RESULTS] are optional, i.e. may be 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 like with 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:

  1. If an item is a reference to a string then the string is inserted as-is (unquoted), and unless the string is empty, adjacent commas are suppressed. This allows concatenating arbitrary text with values formatted by Data::Dumper.

  2. If an item is an object (blessed reference) then only it's type and abbreviated address are shown, unless overridden via the fmt_object option described below.

{OPTIONS}

(See "Default OPTIONS" below to specify most of these statically)

self => objref

If your sub is a method, your can pass self => $self and 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 same self value.

fmt_object => CODE

Format a reference to a blessed thing, or the value of the self option, if passed, whether blessed or not.

The sub is called with args ($state, $thing). It should return either $thing or an alternative representation string. By default, the type/classname is shown and an abbreviated address (see addrvis in Data::Dumper::Interp).

$state is a ref to a hash where you can store anything you want; it persists only during the current fmt_call invocation.

is_public_api => CODE

Recognize a public entry-point in the call stack.

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 is sub{ $_[1][3] =~ /(?:::|^)[a-z][^:]*$/ }, which looks for any sub named with an initial lower-case letter; this is based on the convention that internal subs start with an underscore or capital letter (such as for constants).

$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]

Usually {OPTIONS} can be omitted, so the short-hand form reduces to log_methcall $self, [INPUTS], [RESULTS].

$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.

Default OPTIONS

our %SpreadsheetEdit_Log_Options = (...); in your package will be used to override the built-in defaults (but are still overridden by {OPTIONS} passed in individual calls).

Debug Utilities

btw string,string,...

btwN numlevels,string,string,...

For internal debug messages (not related to the other functions).

btw prints a message to STDERR preceeded by "linenum:" giving the line number of the call to btw. A newline is appended to the message unless the last string string already ends with a newline.

This is like warn 'message' when the message omits a final newline; but with a nicer presentation.

btwN displays the line number of the call <numlevels> earlier in the call stack.

Not exported by default.

oops string,string,...

Prepends "\n<your package name> oops:\n" to the message and then chains to Carp::confess for backtrace and death.

Not exported by default.

SEE ALSO

Data::Dumper::Interp

AUTHOR

Jim Avera (jim.avera gmail)

LICENSE

Public Domain or CC0