Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Named anonymous subs

by blokhead (Monsignor)
on Nov 05, 2003 at 23:39 UTC ( [id://304903]=note: print w/replies, xml ) Need Help??


in reply to Named anonymous subs

Wow, this is a very interesting trick. I like it a lot. But it's too bad it doesn't help DProf give useful information for anonymous subs:
use Carp; my $i = 0; sub foo { sub { local *__ANON__ = "local_subref_" . $i++; carp "blokhead"; }; } foo()->() for 1 .. 3; __OUTPUT__ $ perl -d:DProf test.pl blokhead at test.pl line 7 main::local_subref_0() called at test.pl line 12 blokhead at test.pl line 7 main::local_subref_1() called at test.pl line 12 blokhead at test.pl line 7 main::local_subref_2() called at test.pl line 12 blokhead at test.pl line 7 main::local_subref_3() called at test.pl line 12 $ dprofpp tmon.out Total Elapsed Time = 0.079705 Seconds User+System Time = 0.049705 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name ... 0.00 - 0.020 3 - 0.0066 main::__ANON__ ...
Boo!! DProf still plops everything into main::__ANON__. I've run into this problem before trying to profile code that uses liberal amounts of anonymous subs, and it's quite annoying. Unfortunately I don't know enough about the internals of Perl and DProf to figure out a "clever" solution like yours that works for profiling code (other than using other *Prof modules)...

blokhead

Replies are listed 'Best First'.
Re^2: Named anonymous subs
by fluffy (Scribe) on Oct 02, 2004 at 18:41 UTC

    As maintainer of Class::MethodMaker, I have more than a passing interest in this technique: C::MM generates anonymous routines by the bucket-load, and as well as debugging, I'm particularly interested in profiling, too.

    I'd been meaning to do something about this for a couple of years now, and this thread finally galvanized me into action. After two days of tinkering with it, and several false starts, I've finally come up with this XS incantation:

    void set_sub_name(SV *sub, char *pname, char *subname, char *stashname) CODE: CvGV((GV*)SvRV(sub)) = gv_fetchpv(stashname, TRUE, SVt_PV); GvSTASH(CvGV((GV*)SvRV(sub))) = gv_stashpv(pname, 1); GvNAME(CvGV((GV*)SvRV(sub))) = savepv(subname); GvNAMELEN(CvGV((GV*)SvRV(sub))) = strlen(subname);

    The pname is the package name, the subname the subname, and stashname is the name of a stash to generate to attach the code to, to avoid overwriting the original stash (which is the package the code was compiled in), or the ANON entry in the pname stash. The above certainly appears to work, both with stack traces & the profiler, and doesn't break my code. I was concerned that generating a new stash for each subr might hurt the memory consumption, but empirical testing suggests that the effect is minimal-to-nil.

    I'm no XS programmer, so I'd appreciate any constructive feedback anyone has.

      I ran into similar issues when developing the Perl 6 metamodel stuff for Pugs, and more recently with Class::MOP. I use the Sub::Name module which has worked great for me, it is also written in XS, you might be able to get a few pointers out of the code (or better yet, just use it, why reinvent the wheel).

      Of course I might also be 2 years to late with this comment too :)

      -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://304903]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-04-19 23:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found