NAME

Devel::Probe - Quick & dirty code probes for Perl

VERSION

Version 0.000004

SYNOPSIS

use Devel::Probe;
...
Devel::Probe::trigger(sub {
    my ($file, $line) = @_;
    # probe logic
});
Devel::Probe::config(%config);
...
Devel::Probe::enable();
...
Devel::Probe::disable();

DESCRIPTION

Use this module to allow the possibility of creating probes for some lines in your code.

The probing code is installed when you import the module, and it is disabled. In these conditions, the probe code is light enough that it should cause no impact at all in your CPU usage.

You can call trigger(\&coderef) to specify a piece of Perl code that will be called for every probe that triggers.

You can call config(\%config) to specify a configuration for the module, including what lines in your code will cause probes to be triggered. This call will always disable the module as a first action, so you always need to explicitly enable it again, either from the configuration itself or in a further call to enable().

You can call add_probe(file, line, type) to manually add a probe; this is what gets called from config().

You can call enable() / disable() to dynamically activate and deactivate probing. You can check this status by calling is_enabled().

You can call install() / remove() to install or remove the probe handling code. You can check this status by calling is_installed(). When you import the module, install() is called automatically for you.

You can call clear() to remove all probes.

You can call dump() to print all probes to stderr.

CONFIGURATION

An example configuration hash looks like this:

my %config = (
    actions => [
        { action => 'disable' },
        { action => 'clear' },
        { action => 'define' ... },
        { action => 'dump' },
        { action => 'enable' },
    ],
);

Possible actions are:

  • disable: disable probing.

  • clear: clear current list of probes.

  • dump: dump current list of probes to stderr.

  • enable: enable probing.

  • define: define a new probe. A full define action looks like:

    my %define = (
        action => 'define',
        type => PROBE_TYPE,
        file => 'file_name',
        lines => [ 10, 245, 333 ],
    );

    The type field is optional and its default value is once. Possible values are:

    • once: the probe will trigger once and then will be destroyed right after that.

    • permanent: the probe will trigger every time that line of code is executed.

EXAMPLE

This will invoke the trigger callback the first time line 21 executes, and take advantage of PadWalker to dump the local variables.

use Data::Dumper qw(Dumper);
use PadWalker qw(peek_my);
use Devel::Probe;

Devel::Probe::trigger(sub {
    my ($file, $line) = @_;
    say Dumper(peek_my(1)); # 1 to jump up one level in the stack;
});

my %config = (
    actions => [
        { action => 'define', # type is 'once' by default
          file => 'probe my_cool_script.pl', lines => [ 13 ] },
    ],
);
Devel::Probe::config(\%config);
Devel::Probe::enable();
my $count;
while (1) {
    $count++;
    my $something_inside_the_loop = $count * 2; # line 21
    sleep 5;
}
Devel::Probe::disable();

SUGGESTIONS

One typical use case would be to have a signal handler associated with a specific signal, which when triggered would disable the module, read the configuration from a given place, reconfigure the module accordingly and then enable it.

Another use case could be a similar kind of control using remote endpoints to deal with reconfiguring, disabling and enabling the module.

TODO

  • Probes are stored in a hash of file names; per file name, there is a hash of line numbers (with the probe type as a value). It is likely this can be made more performant with a better data structure, but that needs profiling.

AUTHORS

  • Gonzalo Diethelm gonzus AT cpan DOT org

  • Ben Tyler btyler AT cpan DOT org