ummon
ummon

Reputation: 43

How to override calls to a module function and then reference that original function in override?

I've got a huge perl script that has hundreds of calls to a couple functions in a module, and I need to track how much time has elapsed during execution of those functions.

Problem: I can't install Devel::NYTProf (won't compile on perl 5.8.8 on my machine), and adding Devel::Timer calls around each instance of those two functions would be extremely time consuming.

I thought about overriding the calls to those two functions, and within my overrides execute those two functions with just a couple Devel::Timer calls wrapped around it. My initial tries ended up in a recursive loop.

For example:

use strict;
Use SomePackage::SomeModule;
Use Devel::Timer;

my $t = Devel::Timer->new();

$someThing = new SomePackage::SomeModule();
$someThing->someFunction('test1','test2');

$t->mark('END');
$t->report();

sub SomePackage::SomeModule::someFunction {
    $t->mark('start someFunction');
    $someThing->someFunction(@_)
    $t->mark('end someFunction');
}

That obviously doesn't work, but I have no clear leads on a solution.

Any ideas or tips to point me to the correct way?

Upvotes: 2

Views: 264

Answers (2)

ummon
ummon

Reputation: 43

Thanks to ikegami for the basics, I was able to get the following code working:

use strict;
use SomePackage::SomeModule;
use Devel::Timer;

my $t = Devel::Timer->new();

$someThing = new SomePackage::SomeModule();

my $someFunctionRef = \&SomePackage::SomeModule::someFunction;

my $someFunctionTrack = sub {
    $t->mark('start someFunction');
    $someFunctionRef->(@_);
    $t->mark('end someFunction');
};

no warnings qw( redefine );
*SomePackage::SomeModule::someFunction = $someFunctionTrack;

$someThing->someFunction('test1','test2');

$t->mark('END');
$t->report();

Upvotes: 2

ikegami
ikegami

Reputation: 385849

my $old_f = \&f;
my $new_f = sub { ... $old_f->(...) ... };
no warnings qw( redefine );
*f = $new_f;

Upvotes: 2

Related Questions