If I understand you correctly, you want to trap each entry and exit to the subroutines of a certain package.

As theorbtwo has noted, you can trap each and every subroutine call that happens in perl with &DB::sub, and then you check for the called package. A small example is (for perl 5.8.2)

BEGIN { sub DB::sub { my ($r, @r, $s); $s = $DB::sub; $s=~/^T::/ or goto &$s; warn "entering $s\n"; if (wantarray) { @r = &$s; } elsif (defined wantarray) { $r = &$s; } else { &$s; } warn "exitting $s\n"; wantarray ? @r : $r; } $^P |= 1; } { package T; $r = "r"; sub f { $_[0].$r.n(); } sub n { @l = l(); 2, chr(@l); } sub l { -5..4; } } sub g { T::f($_[0]."a"); }; print g("b");
(Thanks to wog for bringing $^P in my attention in Re^2: How's your Perl? (II).)

The above aspect, however, has some problems. It might be slow as it has to catch all subroutine calls, not only those in a certain package, it does not work for anonymous subs, and it might be difficult to make it work if you use the perl debugger or use DB::sub for any other purpose.

As a different approach, you could replace each subroutine in the package with a different subroutine. This, however, has the backdraw that the subroutines you want to trap have to be defined by the time you install the trapping code, as a special case you can not trap AUTOLOADED subs this way. An example is:

{ for $n (keys %T::) { if (defined &{$T::{$n}}) { my $s = $n; my $f = \&{$T::{$n}}; $T::{$n} = sub { my ($r, @r); warn "entering $s\n"; if (wantarray) { @r = &$f; } elsif (defined wantarray) { $r = &$f; } else { &$f; } warn "exitting $s\n"; wantarray ? @r : $r; } } } } { package T; $r = "r"; sub f { print $_[0].$r.n(); } sub n { @l = l(); 2, chr(@l); } sub l { -5..4; } } sub g { T::f($_[0]."a"); }; g("b");

(Pity overloading "&{}" can not catch named subroutine calls, as that would have been a very elegant solution.)

Update: Note that these codes get much shorter if you only want to trace subroutine entry, not exit, as you don't have to mess with the contexts. You might only want to trace calls that come from a different package. That should be possible with caller.


In reply to Re: Package level scope callbacks. by ambrus
in thread Package level scope callbacks. by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.