Devel::Trace hack

Ovid on 2006-08-16T11:00:03

Devel::Trace is handy. Just do this:

perl -d:Trace some_prog.pl 2>logfile

And in another terminal, tail -f logfile.

That let's me run an interactive program in one window and watch the program execution flow in another. However, this shows everything and you may get overwhelmed with detail. So I hacked it:

package Devel::Trace;
$VERSION = '0.10';
$TRACE   = 1;
$REGEX   = qr//;

# This is the important part.  The rest is just fluff.
sub DB::DB {
    return unless $TRACE;
    my ( $p, $f, $l ) = caller;
    my $code = \@{"::_<$f"};
    my $line = ">> $f:$l: $code->[$l]";
    print STDERR $line if $line =~ $REGEX;
}

sub import {
    my $package = shift;
    while ( defined( $_ = shift @_ ) ) {
        if ( $_ eq 'trace' ) {
            my $caller = caller;
            *{ $caller . '::trace' } = \&{ $package . '::trace' };
        }
        elsif ( $_ eq 'match' ) {
            my $regex = shift;
            $REGEX = qr/$regex/;
        }
        else {
            use Carp;
            croak "Package $package does not export `$_'; aborting";
        }
    }
}

my %tracearg = ( 'on' => 1, 'off' => 0 );

sub trace {
    my $arg = shift;
    $arg = $tracearg{$arg} while exists $tracearg{$arg};
    $TRACE = $arg;
}

1;

That's "not ready for prime time", but now I can do this:

perl -d:Trace=match,some_regex some_prog.pl 2>logfile

And only lines which match the regex are printed. That's handy if you want to limit it to a particular package. It's not perfect, but it was a good enough hack to let me see a nasty execution flow error that I was having trouble following in the debugger (the debugger can be a right pain to use with interactive programs).