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

Devel::Spy - Spy on your objects and data

DESCRIPTION

Devel::Spy is a transparent wrapper over your objects and data. All accesses are logged. This is useful for instrumenting "black box" code. You can just look at see what the code used and how it used it.

I used it to find out what attributes and values were being used as booleans and then wrote tests that fed the "black box" code with inputs covering all possible combinations. By using Devel::Spy I didn't have to be an expert in the code I was looking at knew I wasn't going to overlook any parameters.

SYNOPSIS

# Create an event log and function to write to it.
use Devel::Spy;
my ( $log, $logger ) = Devel::Spy->make_eventlog();

# Wrap an object and let a black box do something to it.
my $obj = Some::Thing->new;
my $wrapped = Devel::Spy->new( $obj, $logger );
black_box_function( $obj );

# Look at what happened.
for my $event ( @$log ) {
    print "$event\n";
}

CLASS METHODS

WRAPPED THING = Devel::Spy->new( THING, LOGGING FUNCTION )

Wraps a thing in a transparent proxy object. This is how you instrument your things.

( ARRAY REF, LOGGING FUNCTION ) = Devel::Spy->make_eventlog

Returns an array reference and a logging function. Pass the logging function into any Devel::Spy object you wish to have use the same event log.

This is how you can make a shared event log that associates all actions with their sources.

LOGGING FUNCTION = Devel::Spy->make_tattler

Returns a plain logging function which just prints to STDOUT or whatever else is currently selected. Normally I prefer using ->make_eventlog because the final output is much nicer but when there's a bug in Devel::Spy then it's useful to get it to just dump its operation as it runs.

LOGGING FUNCTION = Devel::Spy->make_null_eventlog

Returns a null eventlog.

CAVEATS

This is really funky code. There's a somewhat high concentration of magic here. It worked on the 5.8.7 and 5.9.3 I tested it on. It might work as far back as 5.6.0. Or maybe farther back? Try it. Report back.