Perl prints out all subs arguments on every call at runtime

I'm looking for a way to debug the printing of each subroutine call from the namespace Myapp::*

(for example, without resetting CPAN modules), but without having to edit each .pm

file manually
to insert some module or print statement. In the meantime, there is no need to worry about it. ”

I am just researching (better to say: trying to understand) package DB

which allows me to track execution (using a shebang #!/usr/bin/perl -d:Mytrace

)

package DB;
use 5.010;

sub DB {
    my( $package, $file, $line ) = caller;
    my $code = \@{"::_<$file"};
    print STDERR "--> $file $line $code->[$line]";
}

#sub sub {
#    print STDERR "$sub\n";
#    &$sub;
#}

1;

      

and looking for a way to use the call sub

to print the actual arguments of the callable sub

from the namespace Myapp::*

.

Or here is some simpler method for

  • concatenate line-execution trace DB::DB

  • with a dump of every argument of the subroutine call (and its return values, if possible)?
+3


source to share


1 answer


I don't know if this is considered "simpler" in any common sense of the word, but you can walk around in the symbol table and wrap all the functions in code that prints their arguments and returns values. Here's an example of how this can be done:



#!/usr/bin/env perl

use 5.14.2;
use warnings;

package Foo;

sub first {
    my ( $m, $n ) = @_;

    return $m+$n;
}

sub second {
    my ( $m, $n ) = @_;

    return $m*$n;
}

package main;

no warnings 'redefine';

for my $k (keys %{$::{'Foo::'}}) {
    my $orig = *{$::{'Foo::'}{$k}}{CODE};
    $::{'Foo::'}{$k} = sub {
        say "Args: @_";
        unless (wantarray) {
            my $r = $orig->(@_);
            say "Scalar return: $r";
            return $r;
        }
        else {
            my @r = $orig->(@_);
            say "List return: @r";
            return @r
        }
    }
}

say Foo::first(2,3);
say Foo::second(4,6);

      

+3


source







All Articles