Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept nonexistent methods call in Perl

Tags:

perl

autoload

I try to intercept nonexistent methods call in some subclass. Yes, I know about AUTOLOAD, but (for methods) it try to call parent::method first, then UNIVERSAL::method and only then ::AUTOLOAD. But I need call (something like) ::AUTOLOAD at first. Because I want to know what methods subclass try to call from parent.

Give me some advice about it please.

like image 247
bor Avatar asked Aug 04 '11 08:08

bor


2 Answers

  • If you just want to know what methods are being used, you can use some profiling module like Devel::NYTProf.

  • If you want to react to that during your program execution, you can intercept directly the entersub opcode just as the profiling modules do. See the perlguts or profiling module code for more details.

  • You could probably create a 'Monitor' class with FETCH and EXISTS and tie it to the symbol table hash like: tie %Module::Name:: , Monitor;

But unless we know exactly what you are trying to do and why, it's hard to guess what would be the right solution for you.

like image 108
Jiri Klouda Avatar answered Nov 15 '22 10:11

Jiri Klouda


Please heavily consider Jiri Klouda's suggestion that you step back and reconsider what you are trying to accomplish. You almost never want to do what you're trying to do.

But, if you're really sure you want to, here's how to get enough pure Perl rope to hang yourself...

The subs pragma takes a list of sub names to predeclare. As tchrist says above, you can predeclare subs but never actually define them. This will short-circuit method dispatch to superclasses and call your AUTOLOAD immediately.

As for the list of sub names to pass to the pragma, you could use Class::Inspector->methods (thanks to Nic Gibson's answer for teaching me about this module).

According to brian d foy's comment to Nic Gibson's answer, Class::Inspector will not handle methods defined in UNIVERSAL. If you need to do those separately, you can get inspiration from the 'use subs' line in my Class::LazyObject module.

like image 25
daxelrod Avatar answered Nov 15 '22 11:11

daxelrod