Search code examples
perlinternals

In perl, is there a way to make subroutines print their name and arguments when called?


I need to quickly understand which subroutines are being called in a mess of spaghetti code perl modules.

I could write a script to go through all the modules and add code to print out the subroutine name and arguments at the start of every subroutine.

But is there a way to override the internal perl 'subroutine' mechanism itself to do this?

The code is running under mod_perl so I can't easily use a debugger.


Solution

  • You could use Moose::MethodModifiers. I don't know much about Moose, but from the manual I can see you can do it. Here goes.

    #!/usr/bin/perl -w
    use 5.010;
    use strict;
    use Moose;
    
    sub sub_one {
        say "I am sub one!";
    }
    
    sub sub_two {
        say "Guess who!";
    }
    
    # Note that the name of the function being modified isn't passed in in
    # any way
    
    for my $func qw(sub_one sub_two) {
        around $func => sub {
            my $orig = shift;
    
            say "Running ${func}(@_)";
    
            # call the original sub
            my $self = shift;
            $self->$orig(@_);
        }
    }
    
    sub_one(21, 12);
    sub_two();
    

    This produces something like

    cnicutar@aiur:~$ perl method_modifiers.pl
    Running sub_one(21 12)
    I am sub one!
    Running sub_two()
    Guess who!
    

    Please note I'm only a beginner so be cautious about that code.