So if another class wants to extend Foo's functionality, they can just do this:package Foo; our %callbacks = ( pig => sub { ... }, cat => sub { ... }, dog => sub { ... } ); while (...) { # do stuff $choice = ...; $callbacks{$choice}->(@args); }
So far so good. But when I tried using -d:DProf to see which of these callbacks was being slow, I don't get anywhere because DProf doesn't help much with anonymous subs. All of them get lumped into one category, and I get something as uninformative as this:package main; use Foo; $Foo::callbacks{iguana} = sub { ... };
Although there is an option of dprofpp to split the __ANON__ subs into several lines, it still doesn't help me determine which one is the slow one (instead of all subs grouped into the __ANON__ category, I get __ANON__(28), __ANON__(3e), etc). I have to figure out which sub is which by looking at the #Calls column and making an educated guess.%Time ExclSec CumulS #Calls sec/call Csec/c Name 90.73 0.770 0.648 60783 0.0000 0.0000 Foo::__ANON__
It seems like the only way to get DProf to tell me what sub was called is to (obviously) have a named sub, and to call it by name, not just through a code reference. So I've had to resort to something like this, using symbolic references and fully-qualified sub names:
This actually works, and gives good information in DProf, but I'm wondering if this is the best way to get DProf to play nice with my anonymous subs... Also, is this a safe way to keep things, or should I switch back to the hash-based callbacks once I've profiled to my heart's content? Apart from the symbolic reference that I use to make the call, this approach seems reasonable to me.package Foo; sub Foo::callbacks::pig { ... } # no more hash! sub Foo::callbacks::cat { ... } sub Foo::callbacks::dog { ... } while (...) { # do stuff $choice = ...; # of course, we also validate $choice no strict 'refs'; &{"Foo::callbacks::$choice"}(@args); # I feel so dirty! } package main; ## now extend Foo by doing this: use Foo; sub Foo::callbacks::iguana { ... }
The only "gotcha" I'm aware of is one that merlyn brought up in the CB a few days ago -- that SUPER:: won't work, as it's based on the package scope, not the actual name of the containing sub. However, there won't be any OO-things happening in these callbacks, and there's certainly no need to bless anyone into the Foo::callbacks namespace.
blokhead
In reply to Avoiding "Pkg::__ANON__" diagnostics with -d:DProf by blokhead
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |