Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

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

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

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2021-06-21 10:32 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (98 votes). Check out past polls.